2010-02-28 37 views
92

Tôi gặp sự cố:

Tôi đang viết một WebApp mới không có Khung.

Trong index.php tôi Tôi đang sử dụng: require_once('load.php');

Và trong load.php Tôi đang sử dụng để tải require_once('class.php'); tôi class.php.

Trong class.php tôi Tôi đã có lỗi này:

Fatal error: Using $this when not in object context in class.php on line ... (in this example it would be 11)

Một ví dụ như thế nào tôi class.php có chép rằng:

class foobar { 

    public $foo; 

    public function __construct() { 
     global $foo; 

     $this->foo = $foo; 
    } 

    public function foobarfunc() { 
     return $this->foo(); 
    } 

    public function foo() { 
     return $this->foo; 
    } 
} 

Trong index.php của tôi Tôi đang tải có thể foobarfunc() như thế này:

foobar::foobarfunc(); 

nhưng cũng có thể

$foobar = new foobar; 
$foobar->foobarfunc(); 

Tại sao lỗi tới?

+0

nên được công khai ** chức năng ** __construct() – Gordon

+0

trong mã của tôi là chức năng, xin lỗi chỉ cần quên trong ví dụ này – ahmet2106

+1

Thật trùng hợp tôi đã đấu tranh với lỗi này trong khoảng 3 giờ ngày hôm qua! :) – Jack

Trả lời

112

In my index.php I'm loading maybe foobarfunc() like this:

foobar::foobarfunc(); // Wrong, it is not static method 

but can also be

$foobar = new foobar; // correct 
$foobar->foobarfunc(); 

Bạn không thể gọi phương thức theo cách này vì nó không phải là phương pháp tĩnh.

foobar::foobarfunc(); 

Bạn thay vào đó nên sử dụng:

foobar->foobarfunc(); 

Tuy nhiên, nếu bạn đã tạo ra một phương pháp gì đó tĩnh như:

static $foo; // your top variable set as static 

public static function foo() { 
    return self::$foo; 
} 

sau đó bạn có thể sử dụng này:

foobar::foobarfunc(); 
+1

Các biến có cùng tên không phải là một vấn đề. '$ this-> foo' là một thành viên lớp, trong khi' $ foo' chỉ là một biến trong phạm vi hàm (được nhập từ phạm vi toàn cục).Tên chức năng có cùng tên với thành viên cũng không phải là vấn đề. – Gordon

+0

@Gordon: oh, có bạn là đúng, cảm ơn người đàn ông :) – Sarfraz

+102

Bạn không thể sử dụng '$ this' trong một phương thức tĩnh. – Yacoby

9

Nếu bạn đang gọi foobarfunc với resolution scope operator (::), sau đó bạn gọi số đó là statically, ví dụ: ở cấp độ lớp thay vì cấp độ cá thể, do đó bạn là sử dụng $this khi không ở trong ngữ cảnh đối tượng. $this không tồn tại trong ngữ cảnh lớp.

Nếu bạn kích hoạt E_STRICT, PHP sẽ nâng cao một Thông Báo về vấn đề này:

Strict Standards: 
Non-static method foobar::foobarfunc() should not be called statically 

Làm điều này thay vì

$fb = new foobar; 
echo $fb->foobarfunc(); 

Trên một sidenote, tôi đề nghị không sử dụng global bên trong lớp học của bạn.Nếu bạn cần một cái gì đó từ bên ngoài trong lớp học của bạn, vượt qua nó thông qua các nhà xây dựng. Điều này được gọi là Dependency Injection và nó sẽ làm cho mã của bạn dễ bảo trì hơn và ít phụ thuộc vào những thứ bên ngoài.

4

Khi bạn gọi hàm trong ngữ cảnh tĩnh, $this chỉ đơn giản là không tồn tại.

Thay vào đó, bạn phải sử dụng this::xyz().

Để tìm hiểu những gì bối cảnh mà bạn đang ở trong khi một hàm có thể được gọi cả hai tĩnh và trong một trường hợp đối tượng, một cách tiếp cận tốt được nêu trong câu hỏi này: How to tell whether I’m static or an object?

18

Bạn đang gọi một phương thức không tĩnh:

public function foobarfunc() { 
    return $this->foo(); 
} 

sử dụng một tĩnh gọi:

foobar::foobarfunc(); 

Khi sử dụng một tĩnh gọi, chức năng sẽ được gọi (thậm chí nếu không được khai báo là static), nhưng, vì không có thể hiện của một đối tượng, không có $this.

Vì vậy:

  • Bạn không nên sử dụng các cuộc gọi tĩnh cho các phương pháp không tĩnh
  • phương pháp tĩnh của bạn (hoặc tĩnh gọi là phương pháp) không thể sử dụng $ này, mà thông thường chỉ vào dụ hiện tại của lớp, vì không có cá thể lớp khi bạn đang sử dụng các cuộc gọi tĩnh.


Ở đây, các phương pháp của lớp học của bạn đang sử dụng ví dụ hiện tại của lớp, vì chúng cần truy cập vào $foo tài sản của lớp.

Điều này có nghĩa là phương pháp của bạn cần một phiên bản của lớp - điều đó có nghĩa là chúng không thể tĩnh.

này có nghĩa là bạn không nên sử dụng các cuộc gọi tĩnh: bạn nên instanciate lớp, và sử dụng các đối tượng để gọi các phương pháp, giống như bạn đã làm trong phần cuối cùng của bạn mã:

$foobar = new foobar(); 
$foobar->foobarfunc(); 


Để biết thêm thông tin, đừng ngần ngại để đọc, trong cuốn hướng dẫn PHP:


Cũng lưu ý rằng bạn có thể không cần dòng này trong __construct phương pháp của bạn:

global $foo; 

Sử dụng global keyword sẽ làm cho $foo biến, tuyên bố bên ngoài của tất cả các chức năng và các lớp học, visibile từ bên trong phương thức đó ... Và bạn có thể không có biến số $foo.

Để truy cập $fooclass-property, bạn chỉ cần sử dụng $this->foo, như bạn đã làm.

0

$foobar = new foobar; đặt lớp foobar trong $ foobar, không phải là đối tượng. Để nhận đối tượng, bạn cần phải thêm dấu ngoặc đơn: $foobar = new foobar();

Lỗi của bạn đơn giản là bạn gọi phương thức trên lớp, do đó không có $this chỉ tồn tại trong đối tượng.

5

Trước tiên, bạn hiểu một điều, $ số này bên trong một lớp biểu thị đối tượng hiện tại .
Đó là bạn được tạo ra bên cạnh lớp để gọi hàm hoặc biến lớp.

Vì vậy, khi bạn đang gọi hàm lớp của bạn như foobar :: foobarfunc(), đối tượng không được tạo. Nhưng bên trong hàm đó bạn viết trả về $ this-> foo(). Bây giờ ở đây $ này là không có gì. Thats lý do tại sao nó nói Sử dụng $ này khi không trong bối cảnh đối tượng trong class.php

Giải pháp:

  1. Tạo một đối tượng và gọi foobarfunc().

  2. Gọi foo() sử dụng tên lớp bên trong foobarfunc().

+1

hoặc chỉ sử dụng self :: thay vì $ this –

-1

Chỉ cần sử dụng các phương pháp sử dụng lớp foobar->foobarfunc();

+1

Vui lòng chỉ trả lời câu hỏi cũ nếu bạn có gì đó * * mới ** để thêm. – Ajean

4

phương pháp này nhanh: (foobar mới()) -> foobarfunc();

Bạn cần phải nạp lớp học của bạn thay thế:

foobar::foobarfunc(); 

bởi:

(new foobar())->foobarfunc(); 

hay:

$Foobar = new foobar(); 
$Foobar->foobarfunc(); 

Hoặc làm tĩnh chức năng để sử dụng foobar::.

class foobar { 
    //... 

    static function foobarfunc() { 
     return $this->foo(); 
    } 
} 
0

đơn giản như vậy: ..!

chỉ cần chèn static trước propertyfunction của bạn;

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