Hướng dẫn dùng define global trong PHP

Hướng dẫn dùng define global trong PHP

Nội dung chính

  • Video Biến siêu toàn cục trong PHP
  • Hướng dẫn chi tiết
  • Từ khóa global
  • Ví dụ 1: Sử dụng global
  • Ví dụ 2: Sử dụng $GLOBALS thay cho global
  • Ví dụ 3: Demo khả năng của siêu biến toàn cục
  • Sử dụng biến static
  • Ví dụ 4: demo sự cần thiết của biến static
  • Ví dụ 5: sử dụng biến tĩnh
  • Ví dụ 6: Biến tĩnh với hàm đệ quy
  • Ví dụ 7: Khai báo biến tĩnh
  • Tham chiếu với các biến global và static

Trong bài học này, chúng ta sẽ tìm hiểu về khái niệm biến siêu toàn cục trong PHP. Một vài biến được định nghĩa sẳn trong PHP là “superglobals”, nghĩa là chúng luôn có thể truy cập, bất chấp phạm vi và bạn có thể truy cập chúng từ bên bất kỳ hàm, class hoặc file.

  • Video Biến siêu toàn cục trong PHP
  • Hướng dẫn chi tiết
    • $GLOBALS
    • $_SERVER
      • Vài nét về HTTP
      • $_SERVER là biến siêu toàn cục trong PHP
      • Một số thành phần trong $_SERVER

Video Biến siêu toàn cục trong PHP

Hướng dẫn chi tiết

"Thăm ngàn, kẹp ngần nhưng vẫn không đủ chai ni (trả nợ)" nên dành vài dòng cho QUẢNG CÁO Các bạn cần hosting PHP - WordPress nhanh, rẻ và dễ sử dụng có thể chọn Azdigi nhé. Link đăng ký: NHẬN NGAY ƯU ĐÃI Nếu các bạn đăng ký hosting từ link quảng cáo, mình sẽ có một ít tiền để duy trì và "chai ni".

Các biến superglobal trong PHP là: $GLOBALS, $_SERVER, $_REQUEST, $_POST, $_GET, $_FILES, $_COOKIE, $_SESSION

$GLOBALS

$ GLOBALS là một biến siêu toàn cục trong PHP được sử dụng để truy cập các biến toàn cục từ bất kỳ đâu trong tập lệnh PHP (cũng từ bên trong các hàm hoặc phương thức).

function global_demo() { $bien = 'Biến cục bộ; echo '$bien in global scope: ' . $GLOBALS["bien"] . "\n"; echo '$foo in current scope: ' . $bien. "\n"; } $bien = "Demo content"; global_demo();

PHP lưu trữ tất cả các biến toàn cục trong một mảng gọi là $ GLOBALS [index]. index là tên của biến.

Trong ví dụ bên trên, nếu muốn dùng $bien trong hàm global_demo, các bạn cần truyền theo dạng tham số của hàm. Khi dùng biến siêu toàn cục $GLOBALS[“bien”], các bạn có thể gọi $bien từ bất kỳ đâu.

"Người ta tắt AdsBlock không phải vì người ta dại, mà người ta quý mình nên coi quảng cáo" Hosting WordPress nhanh, rẻ và dễ sử dụng có free SLL hãy chọn Azdigi nhé. Link đăng ký: NHẬN NGAY ƯU ĐÃI Nếu các bạn mua hosting từ link trên, mình sẽ có một ít tiền để duy trì. Cảm ơn

$_SERVER

Vài nét về HTTP

HTTP là viết tắt của “HyperText Transfer Protocol”, hay còn gọi là giao thức truyền tải siêu văn bản. Tức là nó dùng để chuyển và nhận dữ liệu mỗi khi có yêu cầu. HTTP header là phần đầu của HTTP (head là đầu rồi) trong mỗi request mà client gửi tới server cũng như response của server gửi về cho client.

Mỗi khi truy cập vô một url thì chúng ta sẽ thực hiện gửi và nhận nhiều HTTP request nên đồng thời cũng gửi và nhận nhiều HTTP header kèm theo. Bởi vì được “gửi và nhận bởi client và server” nên HTTP header sẽ chứa thông tin chủ yếu về client và server. Cụ thể là thông tin của trình duyệt, thông tin cấu hình server, ngày tháng, thông tin về request page, kiểu dữ liệu truyền tải,…

$_SERVER là biến siêu toàn cục trong PHP

$_SERVER là biến siêu toàn cục trong PHP được dùng để chứa thông tin về headers, đường dẫn, địa chỉ lưu trữ tập lệnh. $_SERVER được thiết lập bởi máy chủ và liên quan trực tiếp đến môi trường chạy hiện tại của tập lệnh PHP.

$ _SERVER có các thuộc tính cơ bản sau:

  • Thiết lập bởi máy chủ web.
  • Trực tiếp liên quan đến môi trường thời gian chạy của tập lệnh php hiện tại.

Một số thành phần trong $_SERVER

$_SERVER[‘PHP_SELF’]: Trả về tên file của file đang được chạy.

$_SERVER[‘REMOTE_ADDR’] Trả về địa chỉ IP từ nơi người dùng đang xem một trang hiện hành

$_SERVER[‘REMOTE_PORT’]: Trả về các cổng được sử dụng trên máy tính của người dùng để giao tiếp với máy chủ web

$_SERVER[‘HTTP_REFERER’]: Trả về URL hoàn chỉnh của trang hiện tại

$_SERVER[‘REMOTE_HOST’] Trả về tên Máy chủ từ nơi người dùng đang xem trang hiện tại

$_SERVER[‘REMOTE_PORT’] Trả về cổng đang được sử dụng trên máy của người dùng để liên lạc với máy chủ web

$_SERVER[‘SCRIPT_NAME’] Trả về đường dẫn của tập lệnh hiện tại

$_SERVER[‘SCRIPT_URI’] Trả về URI của trang hiện tại

Code mẫu: Download

Nếu có thắc mắc, hãy đặt câu hỏi bằng cách comment bên dưới, qua email, hoặc nhắn tin qua Fanpage Góc làm web.

Liên hệ

Phạm vi của biến là bối cảnh trong đó nó được định nghĩa. Đa số các biến PHP chỉ có một phạm vi duy nhất. Phạm vi này bao gồm cả các file được include và require tương ứng. Ví dụ:

$a 1;
include 
'b.inc';
?>

Ở ví dụ trên thì biến $a sẽ sử dụng được trong file b.inc. Tuy nhiên, trong các hàm do người dùng định nghĩa thì ta không sử dụng được biến khai báo ngoài hàm một cách thông thường. Ví dụ:

$a 1/* phạm vi toàn cục */ 

function test()

    echo 
$a/* không sử dụng được biến toàn cục $a như thế này */ 

test();
?>

Ở đoạn mã trên thì ta không thể sử dụng được biến $a trong hàm test() như vậy, lúc này biến $a trong hàm test() lại được hiểu là biến cục bộ của chính hàm test() đó. Để khắc phục điều này thì ta cần phải sử dụng đến từ khóa global.

Từ khóa global

Ta xét một ví dụ sử dụng từ khóa global như sau:

Ví dụ 1: Sử dụng global

$a 1;
$b 2;

function

Sum()
{
    global 
$a$b;$b $a $b;

Sum();
echo 
$b;
?>

Đoạn mã trên sẽ in ra 3. $a và $b là các biến global vì chúng được khai báo ngoài hàm, và chúng được sử dụng trong hàm Sum() bằng cách khai báo lại và đặt từ khóa global để trình dịch hiểu chúng là các biến toàn cục. Một hàm có quyền sử dụng bất kỳ biến global nào và với số lượng tùy ý.

Ở ví dụ dưới đây thể hiện một cách khác để sử dụng biến toàn cục, đó là sử dụng mảng $GLOBALS được định nghĩa sẵn trong PHP:

Ví dụ 2: Sử dụng $GLOBALS thay cho global

$a 1;
$b 2;

function

Sum()
{
    
$GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];

Sum();
echo 
$b;
?>

Mảng $GLOBALS là mảng kết hợp với tên của biến toàn cục với giá trị mà biến toàn cục chứa, theo đó, mỗi biến toàn cục sẽ được hiểu là một phần tử của mảng này, với chỉ số của phần tử mảng chính là tên của biến toàn cục, còn giá trị của phần tử đó chính là giá trị của biến toàn cục. Lưu ý ta có thể sử dụng $GLOBALS ở bất kỳ đâu, đó là bởi vì nó là siêu biến toàn cục (superglobal). Dưới đây là một ví dụ demo về khả năng của siêu biến toàn cục:

Ví dụ 3: Demo khả năng của siêu biến toàn cục


function test_global()
{
    
// Phần lớn các biến được định nghĩa không phải là "super" và yêu cầu
    // sử dụng 'global' để dùng được trong hàm.
    
global $HTTP_POST_VARS;

        echo

$HTTP_POST_VARS['name'];// Siêu biến toàn cục sử dụng được ở mọi nơi và không yêu cầu từ khóa
    // 'global'. Tuy nhiên, hiện nay thì siêu biến toàn cục dạng như
    // HTTP_POST_VARS không còn được khuyến khích sử dụng.
    
echo $_POST['name'];
}

?>

Lưu ý:

Không được sử dụng từ khóa global bên ngoài hàm, khi đó sẽ phát sinh lỗi. Tuy nhiên, ta có thể sử dụng điều này nếu nó nằm trong tập tin được gọi từ hàm.

Sử dụng biến static

Một đặc tính khác của phạm vi biến là biến static. Biến tĩnh chỉ dùng được trong hàm, tuy nhiên thì giá trị của nó không bị mất đi sau khi hàm được thực thi xong. Xét ví dụ sau:

Ví dụ 4: demo sự cần thiết của biến static


function test()
{
    
$a 0;
    echo 
$a;
    
$a++;
}

?>

Ở hàm trên thì câu lệnh $a++; tỏ ra không có tác dụng mỗi khi hàm được gọi, bởi vì mỗi khi được gọi thì giá trị của biến $a lại được đặt thành 0. Để khắc phục điều này thì ta chỉ cần khai báo biến $a là biến tĩnh:

Ví dụ 5: sử dụng biến tĩnh


function test()
{
    static 
$a 0;
    echo 
$a;
    
$a++;
}

?>

Ở ví dụ trên, giá trị của biến $a vẫn được giữ lại, vì thế mỗi khi gọi hàm test() thì giá trị của $a lại tăng một đơn vị.

Biến tĩnh cũng cung cấp một cách để đối phó với hàm đệ quy. Hàm đệ quy là hàm có đặc điểm nó gọi đến chính nó. Cần hết sức cẩn thận khi sử dụng hàm đệ quy bởi vì nó có khả năng đệ quy vĩnh viễn. Bạn phải đảm bảo rằng bạn đã cung cấp cách để dừng đệ quy cho hàm. Ví dụ sau đây sẽ đếm từ 1 đến 10 sử dụng biến tĩnh $count:

Ví dụ 6: Biến tĩnh với hàm đệ quy


function test()
{
    static 
$count 0;$count++;
    echo 
$count;
    if (
$count 10) {
        
test();
    }
    
$count--;
}

?>

Lưu ý:

Từ bản PHP 5.6 ta có thể gán giá trị cho biến tĩnh là kết quả của một biểu thức, nhưng không được gán cho biến tĩnh là lời gọi tới hàm nào đó.

Ví dụ 7: Khai báo biến tĩnh


function foo(){
    static 
$int 0;          // đúng
    
static $int 1+2;        // đúng (PHP 5.6)
    
static $int sqrt(121);  // sai (vì gán lời gọi hàm cho biến tĩnh)$int++;
    echo 
$int;
}

?>

Lưu ý:

Những biến tĩnh được được giải quyết trong thời gian biên dịch.

Tham chiếu với các biến global và static

Zend Engine 1 và PHP 4 thực thi các bổ từ staticglobal theo hình thức là các tham chiếu. Ví dụ như một biến toàn cục được đưa vào trong một hàm với từ khóa global thì bản chất là tạo ra một tham chiếu tới biến toàn cục. Điều này có thể dẫn đến hành vi bất ngờ đối với các địa chỉ như ví dụ sau:


function test_global_ref() {
    global 
$obj;
    
$obj = &new stdclass;
}

function

test_global_noref() {
    global 
$obj;
    
$obj = new stdclass;
}

test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
?>

Ví dụ trên sẽ in ra:

NULL
object(stdClass)(0) {
}

Hành vi tương tự cũng được áp dụng cho câu lệnh static. Khi đó các tham chiếu sẽ không được lưu trữ dưới dạng tĩnh:


function &get_instance_ref() {
    static 
$obj;

    echo

'Static object: ';
    
var_dump($obj);
    if (!isset(
$obj)) {
        
// Gán một tham chiếu tới biến tĩnh
        
$obj = &new stdclass;
    }
    
$obj->property++;
    return 
$obj;
}

function &

get_instance_noref() {
    static 
$obj;

    echo

'Static object: ';
    
var_dump($obj);
    if (!isset(
$obj)) {
        
// Gán một đối tượng cho biến tĩnh
        
$obj = new stdclass;
    }
    
$obj->property++;
    return 
$obj;
}

$obj1 get_instance_ref();
$still_obj1 get_instance_ref();
echo 
"\n";
$obj2 get_instance_noref();
$still_obj2 get_instance_noref();
?>

Ví dụ trên sẽ in ra:

Static object: NULL
Static object: NULL

Static object: NULL
Static object: object(stdClass)(1) {
["property"]=>
int(1)
}

Ví dụ trên cho thấy khi ta gán một tham chiếu tới biến tĩnh thì nó không hề được lưu lại khi ta gọi hàm &get_instance_ref() lần thứ hai.