2008-09-20 21 views
24

Tôi đang gặp sự cố với các biến toàn cục trong php. Tôi có một tập hợp số $screen được đặt trong một tệp, yêu cầu tệp khác gọi là initSession() được xác định trong một tệp khác. initSession() tuyên bố global $screen và sau đó xử lý thêm $ nữa màn hình bằng cách sử dụng giá trị được đặt trong tập lệnh đầu tiên.biến toàn cầu trong php không hoạt động như mong đợi

Làm cách nào có thể?

Để làm cho mọi thứ trở nên khó hiểu hơn, nếu bạn cố gắng đặt lại màn hình $, sau đó gọi số initSession(), nó sẽ sử dụng giá trị được sử dụng lần đầu tiên một lần nữa. Đoạn mã sau sẽ mô tả quá trình. Ai đó có thể đi giải thích điều này?

$screen = "list1.inc";   // From model.php 
require "controller.php";   // From model.php 
initSession();     // From controller.php 
global $screen;     // From Include.Session.inc 
echo $screen; // prints "list1.inc" // From anywhere 
$screen = "delete1.inc";   // From model2.php 
require "controller2.php"   
initSession(); 
global $screen; 
echo $screen; // prints "list1.inc" 

Cập nhật:
Nếu Tôi tuyên bố $screen toàn cầu một lần nữa ngay trước khi đòi hỏi mô hình thứ hai, $ màn hình được cập nhật đúng đối với phương pháp initSession(). Lạ thật.

+3

'global $ a;' tương đương với '$ a = & $ GLOBALS ['a'];'. Nghĩa là, nó tạo một tham chiếu trong phạm vi cục bộ có cùng tên. Bên ngoài một chức năng, bạn luôn ở trong phạm vi toàn cầu. PHP không cung cấp "phạm vi tệp". – Matthew

Trả lời

58

Global KHÔNG làm biến toàn cầu. Tôi biết nó phức tạp :-)

Global nói rằng biến cục bộ sẽ được sử dụng như thể đó là biến có phạm vi cao hơn.

ví dụ:

<?php 

$var = "test"; // this is accessible in all the rest of the code, even an included one 

function foo2() 
{ 
    global $var; 
    echo $var; // this print "test" 
    $var = 'test2'; 
} 

global $var; // this is totally useless, unless this file is included inside a class or function 

function foo() 
{ 
    echo $var; // this print nothing, you are using a local var 
    $var = 'test3'; 
} 

foo(); 
foo2(); 
echo $var; // this will print 'test2' 
?> 

Lưu ý rằng vars toàn cầu là hiếm khi một ý tưởng tốt. Bạn có thể viết mã 99.99999% thời gian mà không cần chúng và mã của bạn dễ bảo trì hơn nhiều nếu bạn không có phạm vi mờ. Tránh global nếu bạn có thể.

+0

Tôi hết lòng đồng ý với việc tránh toàn cầu 'nếu bạn có thể'. Mã này là một phần của một khuôn khổ, chúng tôi đã cố gắng mở rộng một chút, vì vậy chúng tôi không thể tránh được các hình cầu, vì chúng tôi không đặt chúng ở đó. –

+0

có đúng với lớp học không? – Snymax

+0

globals là siêu hữu ích cho kịch bản đơn giản, mặc dù. Esp. nếu bạn có cấu hình và OO không thích hợp. –

4

Bạn cần đặt "toàn màn hình $" trong mọi chức năng tham chiếu đến nó, không chỉ ở đầu mỗi tệp.

1

Phạm vi toàn cầu kéo dài bao gồm và các tệp bắt buộc, bạn không cần sử dụng từ khóa chung trừ khi sử dụng biến từ bên trong hàm. Bạn có thể thử sử dụng mảng $ GLOBALS thay thế.

15

global $foo không có nghĩa là "biến biến này thành toàn cầu, để mọi người có thể sử dụng nó". global $foo có nghĩa là "trong phạm vi chức năng này, sử dụng biến toàn cục $foo".

Tôi giả định từ ví dụ của bạn rằng mỗi lần, bạn đang đề cập đến màn hình $ từ bên trong một hàm. Nếu vậy, bạn sẽ cần phải sử dụng global $screen trong mỗi chức năng.

4

Nếu bạn có rất nhiều biến số mà bạn muốn truy cập trong một nhiệm vụ trong đó sử dụng nhiều chức năng, xem xét thực hiện một đối tượng 'bối cảnh' để giữ những thứ:

//We're doing "foo", and we need importantString and relevantObject to do it 
$fooContext = new StdClass(); //StdClass is an empty class 
$fooContext->importantString = "a very important string"; 
$fooContext->relevantObject = new RelevantObject(); 

doFoo($fooContext); 

Bây giờ chỉ cần vượt qua đối tượng này như một tham số cho tất cả các chức năng. Bạn sẽ không cần các biến toàn cục, và các chữ ký chức năng của bạn luôn sạch sẽ. Nó cũng dễ dàng để sau này thay thế StdClass rỗng với một lớp học mà thực sự có các phương pháp có liên quan trong nó.

0

Bạn phải khai báo biến là toàn cục trước khi xác định giá trị cho biến đó.

+0

Câu trả lời của bạn thêm vào câu trả lời được chấp nhận trước đây và được đánh giá cao là gì? Chăm sóc bình luận và thêm một số mã mẫu? – Yaroslav

0

Vô ích cho đến khi nó ở trong hàm hoặc một lớp. Toàn cầu có nghĩa là bạn có thể sử dụng một biến trong bất kỳ phần nào của chương trình.Vì vậy, nếu toàn cầu không được chứa trong hàm hoặc một lớp thì không sử dụng Global

Các vấn đề liên quan