Php入門教程之PHP 變數基本文法

來源:互聯網
上載者:User

具體方法

PHP 變數

PHP變數用於儲存字元、數字、數組甚至對象內容等,以便在我們需要的地方使用。

定義一個變數的文法:

$變數名 = 值;

使用變數的例子:

 

 代碼如下 複製代碼

 <?php 

 $var_char = "你好!"; 

 echo $var_char; 

 ?>

執行這段代碼輸出的結果是:


1 你好!
從這個例子可以看出,變數名以 $ 開始,標明這是一個變數。變數名以字母(a-z、A-Z)或者底線 _ 開始,後面可以跟任意字母或數字以及底線,但不能是空格。

如下這些變數名是有效:


 $var_char

 $varChar

 $_varChar

 $var_char5

提示

關於變數命名,我們建議變數名以標明其實際語意的組合為佳,如 $my_name 或 $myName 格式。


全域變數global


全域變數便是其中之一,當然這個觀點頗具爭議,有許多人還是建議禁用全域變數,使用不當對造成程式的可讀性很差!結構混亂,調試更是一頭霧水,但是不可否認他的便捷,這便是php為什麼會用全域變數global原因吧!…

今天就遇到了php 全域變數不起作用的問題.

先上一段簡單的代碼:

 代碼如下 複製代碼

<?php
$a = 0 ;
function Test()
{
    $a =1;
}
Test();
echo $a;
?>

上面的代碼中輸出是0,那是因為函數體Test內$a變數被預設設定為局部變數,$a的範圍就是在Test內.修改代碼如下

 代碼如下 複製代碼

<?php
$a = 0 ;
function Test()
{
   global $a;//申明函數體Test內使用的$a變數為global全域變數
   $a =1;
}
Test();
echo $a;
?>

申明函數體Test內使用的$a變數為global全域變數後,使得$a的作用全域,所以輸出為1.
上面的執行個體只是基本的global全域變數知識,下面我們看看複雜點的:

 代碼如下 複製代碼

//A.php 檔案

<?php
function Test_Global()
{
    include 'B.php';
    Test();
}

$a = 0 ;
Test_Global();
echo $a;
?>

//B.php 檔案

<?php
function Test()
{
   global $a;//申明函數體Sum內使用的$a變數為global全域變數
   $a =1;
}
?>


為什麼輸出的卻是0?!!

在使用者自訂函數中,一個局部函數範圍將被引入。任何用於函數內部的變數按預設情況將被限制在局部函數範圍內(包括include 和 require 匯入的檔案內的變數)!
解釋:A.php檔案的內Test_Global是定義好的第三方函數,該函數用include匯入了B.php檔案內的$a的global全域變數,所以$a被限制在Test_Global局部函數範圍內,所以B.php檔案內的$a的作用範圍都在Test_Global內,而不是作用了整個A.php內….

解決方案:

1. 衝出局部函數//A.php 檔案

 代碼如下 複製代碼

<?php
function Test_Global()
{
    Test();
}
include 'B.php'; //將include 從局部Test_Global函數中移出
$a = 0 ;
Test_Global();
echo $a;
?>

//B.php 檔案

<?php
function Test()
{
    global $a;
    $a =1;
}
?>


2.優秀的訪問器

 代碼如下 複製代碼

//A.php 檔案
<?php
include 'B.php';
$a =0;
Set_Global($a);
echo $a;
?>

//B.php 檔案

<?php
function Set_Global(&$var)
{
    $var=1;
}
?>


 

php變數 引用函數 static變數

“無論怎樣聲明變數(按值或按引用),總之在PHP指令碼的任何位置都可以聲明變數。但是,聲明的位置會大大影響訪問變數的範圍。這個可訪問的範圍稱為範圍(scope)” –PHP與MySQL程式設計
在瞭解php變數之前,我們先看看段式記憶體管理架構的記憶體段的劃分。通常作業系統會將實體記憶體劃分為以下幾個邏輯段。


Text-Segment,這個段最大的特點就是唯讀。一般存放可執行代碼,也有可能常量也存放在這裡,比如字串常量
BSS-Segment,這裡存放了那些沒有初始化的變數。某種意義來講,沒有初始化的變數都是垃圾,不可用
Data-Segment,這裡存放了全域變數和靜態變數,直到指令碼運行結束,作業系統才會回收這裡的記憶體空間,變數亦會被銷毀。
Stack-Heap Segment 函數參數與本地變數(也稱局部變數)存放在堆中(stack),還有傳回值等等。用完了,作業系統就會回收這部分記憶體空間。對於C程式員而言,可以自行從棧中(heap)申請記憶體空間,用完了,也需要自己手動釋放。
作為PHP程式言而言,我們關心的是全域變數、靜態變數、局部變數、函數參數以及函數傳回值。局部變數和函數參數基本上一樣,在初始化的時候分配記憶體空間,退出函數後作業系統會回收記憶體空間。而全域變數與靜態變數要直php指令碼運行結束後,記憶體空間才會被釋放。與全域變數不同的時,所有靜態變數在程式執行之前就初始化並且分配了記憶體空間。

注:
1.函數外部聲明靜態變數意義不大,函數內部聲明靜態變數受限於範圍,函數外部不能修改函數內部靜態變數。
2.引用變數,也是變數,只不過它的值是變數的記憶體位址。

php保留字 global和static

 代碼如下 複製代碼
<?php
$i = $j = 8;
function global_var() {
   global $j, $b;
   $c = $j = $b = $i = 4;
}
global_var();
echo "i:$i, j:$j b:$b c:$c n"; //i:8, j:4 b:4 c:
?>

函數外和內都有變數$i,但是他們二個是完全不同的變數。函數外的$i是全域變數,該記憶體空間直到指令碼運行結束後才會被釋放。函數內的$i是局部變數,程式流經過函數的時候,初始化,退出函數的時候,記憶體被系統回收,再次調用函數,則再次分配記憶體空間和回收記憶體空間。二次分配的記憶體空間有可能是同一記憶體位址,也有可能不能同一記憶體位址。
與$i不同的是$j,通過關鍵字global將局部變數”轉為”全域變數。當調用函數global_var()的時候,並不會重新給$j分配記憶體空間。同樣的,可以在函數外列印$b,卻不能列印$c是因為$b是全域變數,不會被銷毀。而$c則不能列印,$c已經不存在了,在退出函數就給銷毀了。

 代碼如下 複製代碼
<?php
$a = 2;
static $b = 2;
static $c = 3;
function global_var() {
    static $i, $c;
    global $j, $a;
    $c = $a = $b = $i = $j = 4;
}
global_var();
echo "a:$a b:$b c:$c i:$i j:$j"; //a:4 b:2 c:3 i: j:4
?>

首先,我們看函數外的$b和$c,即是全域變數又是static變數。這裡static修飾沒有太大的意義,因為他們都存放在資料區段(data-segment),直到指令碼運行完了之後才會被回收。然後,我們再看函數裡面的$i和$c,函數調用後,$i和$c其實都沒有被回收,但是$i輸出是NULL和$c輸出是3,這是因為他們的範圍是函數內部,不是函數外部,也就是說$i和$c在函數外是不可見的。函數內static變數的意義就在於此:僅函數內部可見且不會被銷毀。也就是說,保證函退出函數,變數也不會被回收,但又不會被其它函數修改。(註:函數外和函數內的$c是二個不同的變數)

 代碼如下 複製代碼
<?php
function global_var() {
   static $i;
   ++$j;
   ++$i;
   echo "j:$j i:$i n";
}
global_var(); //j:1 i:1 
global_var();  //j:1 i:2
global_var();  //j:1 i:3
?>

上例中,變數$j一直都是1,而$i每調用一次就累加1。這是因為,局部變數存放在堆段,每次退出函數時都會被回收。而$i存放在存放在資料區段(data-segment),直到程式執行完畢才會被回收。我們平常說的static變數,如果沒有特別指明,都說的是函數內部的static變數。

引用函數與static變數
既然static變數要直到指令碼執行結束,才會被銷毀。那麼,有沒有辦法訪問該變數的值呢?我們來看看下面的樣本:

 代碼如下 複製代碼
<?php
get_local_static_var();
$ptr = &get_local_static_var();
get_local_static_var();
++$ptr;
get_local_static_var();
what_i($ptr);
get_local_static_var();  //??
what_p($ptr);
get_local_static_var();  //??
 
function &get_local_static_var() {
    static $i;
    ++$i;
    echo "i:$i n";
    return $i;
}
 
function what_i($ptr) {
   $i = &get_local_static_var();
   ++$i;
   ++$ptr;
}
 
function what_p(&$ptr) {
   $i = &get_local_static_var();
   ++$i;
   ++$ptr;
}
?>

二個凝問號處,分別輸出是8和12。這就說明了只要變數沒有被銷毀,還是可以被訪問。我們可以通過引用函數將static變數的地址返回其它函數。其它函數則可通過static變數的地址訪問並且修改它的值。
上例第一處??,為什麼是8,而不是9。這是因為what_i($ptr)函數,要求參數是按值傳遞,即此處的$ptr實參值是5,且參數$ptr和全域變數$ptr是二個不同的變數。第二處??的值是12,為什麼不是11的道理亦是如此。what_p(&$ptr)函數,要求參數是按引用傳遞,即此處的$ptr是指向static變數$i的地址,需要注意的是參數$ptr和全域變數$ptr也是二個不同的變數,只不過他們都指向同一個地方。

drupal應用賞析
drupal定義了一個drupal_static函數,其它函數的static變數都存放在一個數組中,然後對drupal應用到的所有static進行統一管理,比如賦值,重設,刪除等。我覺得,這是一個好辦法。

 代碼如下 複製代碼

<?
function &drupal_static($name, $default_value = NULL, $reset = FALSE) {
  static $data = array(), $default = array();
  if (!isset($name)) {
    foreach ($default as $name => $value) {
      $data[$name] = $value;
    }
    return $data;
  }
  if ($reset) {
    if (array_key_exists($name, $default)) {
      $data[$name] = $default[$name];
    }
    else {
      return $data;
    }
  }
  elseif (!array_key_exists($name, $data)) {
    $default[$name] = $data[$name] = $default_value;
  }
  return $data[$name];
}
 
function ip_address() {
  $ip_address = &drupal_static(__FUNCTION__);
 
  if (!isset($ip_address)) {
    $ip_address = $_SERVER['REMOTE_ADDR'];
 
    if (variable_get('reverse_proxy', 0)) {
      if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
        $reverse_proxy_addresses = variable_get('reverse_proxy_addresses', array());
        if (!empty($reverse_proxy_addresses) &&
     in_array($ip_address, $reverse_proxy_addresses, TRUE)
    ) {
          $ip_address_parts = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
          $ip_address = trim(array_pop($ip_address_parts));
        }
      }
      if (array_key_exists('HTTP_X_CLUSTER_CLIENT_IP', $_SERVER)) {
        $ip_address = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
      }
    }
  }
 
  return $ip_address;
}
 
ip_address();
//在drupal中很多這樣的應用方式,將其它函數的static變數都存放到一個地方,即drupal_static的data中,然後再統一管理,比如重設等等。
?>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.