萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> Php入門教程之PHP 變量基本語法

Php入門教程之PHP 變量基本語法

變量是php中非常常用的一個東西,所有的操作都要經過變量來傳遞,下面我來給各位同學介紹在php中變量的一些常用用法與關於php變量基礎知識。

具體方法

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中,然後再統一管理,比如重置等等。
?>

copyright © 萬盛學電腦網 all rights reserved