2011-12-22 34 views
12

Tôi đã đăng một số câu hỏi trước đây về việc sử dụng Không gian tên trong PHP và từ những gì tôi nhận được, mã ví dụ này tôi có bên dưới sẽ hoạt động.Không thể tìm thấy Class với PHP Namespace

Tuy nhiên tôi gặp lỗi khi cố gắng sử dụng Không gian tên trong PHP như thế này. Dưới đây là lỗi đầu tiên khi chạy đoạn code dưới đây như là ...

Fatal error: Class 'Controller' not found in E:\Controllers\testing.php on line 6 

E: \ khiển \ testing.php tập

<?php 
use \Controller; 

include('testcontroller.php'); 

$controller = new Controller; 
$controller->show(); 
?> 

E: \ khiển \ testcontroller.php tập

<?php 
use \Library\Registry; 

namespace Controller 
{ 
    class Controller 
    { 
     public $registry; 

     function __construct() 
     { 
      include('E:\Library\Registry.class.php'); 
      $this->registry = new Registry; 
     } 

     function show() 
     { 
      echo $this->registry; 
      echo '<br>Registry was ran inside testcontroller.php<br>'; 
     } 
    } 
} 
?> 

E: \ Library \ Registry.class.php tập

<?php 
namespace Library\Registry 
{ 
    class Registry 
    { 
     function __construct() 
     { 
      return 'Registry.class.php Constructor was ran'; 
     } 
    } 
} 
?> 

Như bạn thấy, tôi đã cố gắng làm cho nó đơn giản nhất có thể chỉ để có được phần Không gian làm việc. Tôi đã thử các biến thể khác nhau và dường như không thể tìm ra.

Trả lời

22

Ngay cả khi sử dụng câu lệnh use, bạn cần xác định không gian tên của lớp bạn đang cố gắng tạo nhanh. Có rất nhiều ví dụ ở đây: http://www.php.net/manual/en/language.namespaces.importing.php

Để hiểu nó tốt hơn, tôi sẽ mô tả cho bạn cách hoạt động. Trong trường hợp của bạn, khi bạn làm use \Controller, toàn bộ không gian tên Controller sẽ có sẵn cho bạn, nhưng không phải là các lớp trong không gian tên này. Vì vậy, ví dụ:

<?php 
include('testcontroller.php'); 

use \Controller; 

// Desired class is in namespace! 
$controller = new Controller\Controller(); 

// Error, because in current scope there is no such class 
$controller = new Controller(); 

$controller->show(); 
?> 

Một ví dụ khác:

testcontoller.php:

<?php 
namespace Some\Path\To\Controller; 

class Controller 
{ 
    function __construct() 
    { 

    } 

    function show() 
    { 
     echo '<br>Was run inside testcontroller.php<br>'; 
    } 
} 
?> 

testing.php:

<?php 
include('testcontroller.php'); 

use \Some\Path\To\Controller; 

// We now can access Controller using only Controller namespace, 
// not Some\Path\To\Controller 
$controller = new Controller\Controller(); 

// Error, because, again, in current scope there is no such class 
$controller = new Controller(); 

$controller->show(); 
?> 

Nếu bạn muốn nhập khẩu giống hệt Controllerlớp, bạn cần làm use Controller\Controller - sau đó lớp này sẽ có thể truy cập trong phạm vi hiện tại của bạn.

+0

Ví dụ tốt, tôi đã tìm ra điều này trong đêm qua nhưng tốt cho bạn để mô tả nó. Vì vậy, tôi nghĩ rằng tôi sẽ tốt hơn hết để đặt tất cả các lớp 'Thư viện' vào cùng một không gian tên như' Thư viện' và sau đó trên bộ kiểm tra ở trên, tôi có thể sử dụng 'sử dụng Thư viện \ Classname' cho mỗi lớp trong thư viện mà tôi cần trong đó điều khiển để tôi có thể đánh giá chúng như thế này 'mới Registry' vv ... trên http://www.php.net/manual/en/language.namespaces.importing.php Tôi nghĩ rằng đó là nói rằng đây là 'nhập khẩu toàn cầu class' vì vậy tôi đã không chắc chắn nếu nó là một ý tưởng tồi – JasonDavis

+0

Tôi đang cố gắng để hạn chế dependecies của mỗi lớp, đó là lý do tại sao đối với tôi nó không phải là khó sử dụng tên đầy đủ đủ điều kiện cho lớp. – Timur

+0

Thats sai: Với 'use' bạn cũng định nghĩa một bí danh cho một lớp cụ thể. Trong ví dụ 'use \ Controller; Bộ điều khiển mới, 'nó không phải là rất rõ ràng, nhưng bạn có thể thử' sử dụng Vendor \ Package \ Component \ Controller; Bộ điều khiển mới'. Ý tôi là: Sai, bạn cần xác định không gian tên của một lớp _ trong mọi trường hợp_. Xem liên kết trong bình luận jasondeavis. Mô tả của nó, cách PHP giải quyết các tên lớp tương đối. – KingCrunch

5

Khi bạn đặt một lớp Controller trong không gian tên Controller, sau đó bạn phải tham khảo nó như vậy:

$controller = new Controller\Controller(); 

\Controller sẽ là một lớp trong toàn cầu (mặc định) namespace, ví dụ như nếu bạn sử dụng không không gian tên nào cả.

+0

không nghĩ rằng bạn cần phải làm điều đó vì 'điều khiển sử dụng; 'tuyên bố – Ascherer

+0

@Cassy yeah đó là lý do tại sao tôi sử dụng' điều khiển sử dụng;' vì vậy hy vọng tôi sẽ không phải làm điều đó phương pháp xấu xí – JasonDavis

+0

@Casey tôi đã cố gắng nó chỉ là để xem những gì sẽ xảy ra và nó đã thay đổi lỗi thành 'Fatal error: Class 'Controller \ Registry'' – JasonDavis

0

thử

<?php 
use \Library\Registry; 

namespace Controller; 
class Controller 
{ 
    public $registry; 
    function __construct() 
    { 
     include('E:\Library\Registry.class.php'); 
     $this->registry = new Registry; 
    } 
    function show() 
    { 
     echo $this->registry; 
     echo '<br>Registry was ran inside testcontroller.php<br>'; 
    } 
} 
?> 

<?php 
namespace Library\Registry; 
class Registry 
{ 
    function __construct() 
    { 
     return 'Registry.class.php Constructor was ran'; 
    } 
} 
?> 
+0

Tôi đã thử nhưng không may mắn vẫn là thông báo lỗi tương tự – JasonDavis

2

Kỳ lạ thay tôi đã phát hiện ra rằng trong mã ví dụ của tôi từ câu hỏi trên, nếu tôi thay đổi tất cả các Namespace's được định nghĩa một cái gì đó giống như MyLibrary nên nó sẽ giống như mã này bên dưới ...

E: \ Library \ Registry.class.php Tệp

<?php 
namespace MyLibrary 
{ 
    class Registry 
    { 
     function __construct() 
     { 
      echo 'Registry.class.php Constructor was ran'; 
     } 
    } 
} 
?> 

Sau đó, khi tôi sử dụng use MyLibrary\Registry; trong tập tin khác, tôi có thể truy cập vào nó làm thế nào tôi đã lên kế hoạch ...

$this->registry = new Registry; 

Lý do này là rất xa lạ với tôi là điều này bây giờ làm cho một tên lớp dường như là Namespace. Vì vậy, tôi sẽ không cần phải thiết lập một không gian để 'MyLibrary \ Library' để truy cập vào Registry thay vào đó tôi sẽ làm điều đó như tôi đã cho thấy trong câu trả lời này để có thể truy cập nó với chỉ cần gọi tên của lớp.

Tôi hy vọng điều này có ý nghĩa và giúp người khác. Tôi sẽ không chấp nhận điều này như là câu trả lời vì tôi hy vọng ai đó có nhiều bí quyết hơn sẽ đến và đăng câu trả lời tốt hơn bằng cách giải thích

6

Không phải là ý tưởng hay để đặt tên cho không gian tên, như lớp học (và tôi nghĩ rằng đây là những gì xảy ra ở đây).Có lúc bạn xác định bí danh qua use Controller referenes này hoặc là một lớp \Controller, hoặc không gian tên \Controller, nhưng lớp học của bạn, bởi vì nó nằm trong không gian tên, được đặt tên \Controller\Controller1

use Controller; 
$class = new Controller\Controller; 

hoặc

$class = new \Controller\Controller; 

hoặc

use Controller\Controller; 
$class = new Controller; 

Ý tưởng là, thời điểm bạn cố gắng cess một lớp với tên tương đối của nó nó cố gắng để bản đồ "phần đầu tiên" chống lại bất kỳ bí danh được xác định bằng cách sử dụng use (remeber use MyClass là giống như use MyClass as MyClass. Điều sau as là bí danh).

namespace MyNamespace\MyPackage\SomeComponent\And\So\On { 
    class MyClass {} 
} 
namespace Another { 
    use MyNamespace\MyPackage\SomeComponent; // as SomeComponent 
    $class =    new SomeComponent\An\So\On\MyClass; 
} 

Như bạn thấy PHP thấy SomeComponent như phần đầu tiên và bản đồ nó chống lại SomeComponent -alias dòng trên.

Bạn có thể đọc thêm về nó trong manual about namespaces.

1 Được gọi là "tên lớp đủ điều kiện", nếu bạn đặt tên cho một lớp có tên đầy đủ của nó.

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