Làm thế nào để từ khóa sử dụng các dòng chữ hoạt động trong PHP và tôi có thể nhập các lớp với nó không?


136

Tôi có một tập tin với một lớp Resp. Đường dẫn là:

C:\xampp\htdocs\One\Classes\Resp.php

Và tôi có một index.phptập tin trong thư mục này:

C:\xampp\htdocs\Two\Http\index.php

Trong index.phptập tin này tôi muốn khởi tạo một lớp Resp.

$a = new Resp();

Tôi biết tôi có thể sử dụng requirehoặc includetừ khóa để bao gồm tệp với một lớp:

require("One\Classes\Resp.php");       // I've set the include_path correctly already ";C:\xampp\htdocs". It works.
$a = new Resp();

Nhưng tôi muốn nhập các lớp mà không sử dụng requirehoặc include. Tôi đang cố gắng hiểu làm thế nào usetừ khóa hoạt động. Tôi đã thử các bước này nhưng không có gì hoạt động:

use One\Classes\Resp;
use xampp\htdocs\One\Classes\Resp;
use htdocs\One\Classes\Resp;
use One\Classes;
use htdocs\One\Classes;    /* nothing works */

$a = new Resp();

Nó nói rằng:

Fatal error: Class 'One\Classes\Resp' not found in C:\xampp\htdocs\Two\Http\index.php

Làm thế nào để từ khóa usehoạt động? Tôi có thể sử dụng nó để nhập các lớp không?


1
Bạn không thể nhập các tập tin. Xin đừng thay đổi dòng chảy. Ngoài ra các không gian tên thực sự không được sử dụng trong PHP. Giống như VB.NET
Cole Johnson

13
@ cole-johnson, không đồng ý với bạn. Symfony được xây dựng xung quanh namespaces. Thực tế không có bất kỳ Symfony nào nếu bạn không sử dụng không gian tên
Green

Câu trả lời:


80

usekhông bao gồm bất cứ điều gì. Nó chỉ nhập không gian tên được chỉ định (hoặc lớp) vào phạm vi hiện tại

Nếu bạn muốn các lớp được tự động tải - hãy đọc về tự động tải


@ G-Man nó trả lời chính những câu hỏi.
zerkms

188

Không, bạn không thể nhập một lớp với usetừ khóa. Bạn phải sử dụng include/ requiretuyên bố. Ngay cả khi bạn sử dụng trình tải tự động PHP, trình tải tự động vẫn sẽ phải sử dụng includehoặc requirenội bộ.

Mục đích sử dụng của từ khóa:

Hãy xem xét một trường hợp trong đó bạn có hai lớp có cùng tên; bạn sẽ thấy lạ, nhưng khi bạn đang làm việc với một cấu trúc MVC lớn, nó sẽ xảy ra. Vì vậy, nếu bạn có hai lớp có cùng tên, hãy đặt chúng vào các không gian tên khác nhau. Bây giờ hãy xem xét khi trình tải tự động của bạn đang tải cả hai lớp (do by require) và bạn sắp sử dụng đối tượng của lớp. Trong trường hợp này, trình biên dịch sẽ bị lẫn lộn đối tượng lớp nào sẽ tải giữa hai. Để giúp trình biên dịch đưa ra quyết định, bạn có thể sử dụng usecâu lệnh để nó có thể đưa ra quyết định cái nào sẽ được sử dụng.

Ngày nay các khung chính sử dụng includehoặc requirethông qua composerpsr

1) nhà soạn nhạc

2) Trình tải tự động PSR-4

Đi qua chúng có thể giúp bạn hơn nữa. Bạn cũng có thể sử dụng một bí danh để giải quyết một lớp chính xác. Giả sử bạn có hai lớp có cùng tên, giả sử Mailercó hai không gian tên khác nhau:

namespace SMTP;
class Mailer{}

namespace Mailgun;
class Mailer{}

Và nếu bạn muốn sử dụng cả hai lớp Mailer cùng một lúc thì bạn có thể sử dụng bí danh.

use SMTP\Mailer as SMTPMailer;
use Mailgun\Mailer as MailgunMailer;

Sau này trong mã của bạn nếu bạn muốn truy cập các đối tượng lớp đó thì bạn có thể làm như sau:

$smtp_mailer = new SMTPMailer;
$mailgun_mailer = new MailgunMailer;

Nó sẽ tham chiếu lớp gốc.

Một số có thể bị nhầm lẫn rằng sau đó không có tên lớp tương tự thì không sử dụng usetừ khóa. Chà, bạn có thể sử dụng __autoload($class)hàm sẽ được gọi tự động khi usecâu lệnh được thực thi với lớp được sử dụng làm đối số và điều này có thể giúp bạn tải lớp trong thời gian chạy khi cần thiết.

Tham khảo câu trả lời này để biết thêm về trình tải tự động lớp.


Tại sao không chỉ sử dụng một tên lớp khác nhau?
thần thánh

15
@divine. Các lớp học có thể là từ các nhà cung cấp bên thứ 3
Dayo

3
@divine. Điều gì nếu cả hai lớp va chạm là từ bên thứ 3?
Dayo

2
@divine Theo quy ước, không gian tên sẽ là <ellerName> / <packName> theo cách đó đã được giải quyết. Theo quy ước, người đóng gói có thể chấp nhận cùng tên nhà cung cấp từ người khác. Và packagist.org là kho lưu trữ PHP được sử dụng để cài đặt các gói của nhà soạn nhạc.
Tpojka

1
@root không quan trọng, nó chỉ cho thời gian chạy những gì sẽ được sử dụng. giống như bạn đang lái xe và tín hiệu cho bạn biết phía trước và bạn bị hỏng, như cách usetuyên bố sẽ cho trình biên dịch tải cái này cho tôi ngay bây giờ. Có nó thân yêu!
Rajan Rawal

23

Đừng lật đổ Namespace là gì.

Không gian tên về cơ bản chỉ là một tiền tố Class (như thư mục trong Hệ điều hành) để đảm bảo tính duy nhất của đường dẫn Class .

Ngoài ra, để làm cho mọi thứ rõ ràng, câu lệnh sử dụng không làm gì cả chỉ đặt bí danh cho Không gian tên của bạn để bạn có thể sử dụng các phím tắt hoặc bao gồm các Lớp có cùng tên nhưng Không gian tên khác nhau trong cùng một tệp.

Ví dụ:

// You can do this at the top of your Class
use Symfony\Component\Debug\Debug;

if ($_SERVER['APP_DEBUG']) {
    // So you can utilize the Debug class it in an elegant way
    Debug::enable();
    // Instead of this ugly one
    // \Symfony\Component\Debug\Debug::enable();
}

Nếu bạn muốn biết Không gian tên PHP và tự động tải (cách cũ cũng như cách mới với Trình soạn thảo) hoạt động như thế nào, bạn có thể đọc bài đăng blog tôi vừa viết về chủ đề này: https://enterprise-level-php.com/ 2017/12/25 / the-magic-đằng sau-autoloading-php-files-using-composer.html


8

Dù sao bạn cũng sẽ phải bao gồm / yêu cầu lớp, nếu không PHP sẽ không biết về không gian tên.
Bạn không cần phải làm điều đó trong cùng một tập tin. Bạn có thể làm điều đó trong một tập tin bootstrap chẳng hạn. (hoặc sử dụng trình tải tự động, nhưng thực tế đó không phải là chủ đề)


4

Vấn đề rất có thể là bạn sẽ cần sử dụng trình tải tự động sẽ lấy tên của lớp (ngắt bởi '\' trong trường hợp này) và ánh xạ nó tới cấu trúc thư mục.

Bạn có thể xem bài viết này về chức năng tự động tải của PHP. Có nhiều triển khai loại chức năng này trong các khung công tác.

Tôi đã thực sự thực hiện một trước đây. Đây là một liên kết .


Có một vấn đề với nó mặc dù. Nó cần một mô hình đệ quy để cho phép nó xây dựng một đường dẫn đầy đủ. Ngay bây giờ nó chỉ xử lý các không gian tên cấp đơn.
Tyler Carter

3

Tôi đồng ý với Green, Symfony cần không gian tên, vậy tại sao không sử dụng chúng?

Đây là cách một lớp trình điều khiển mẫu bắt đầu:

không gian tên Acme \ DemoBundle \ Controller;

sử dụng Symfony \ Bundle \ FrameworkBundle \ Controller \ Controller;

class WelcomeControll mở rộng Trình điều khiển {...}


3

Tôi có thể sử dụng nó để nhập các lớp không?

Bạn không thể làm như thế ngoài các ví dụ trên. Bạn cũng có thể sử dụng từ khóa usebên trong các lớp để nhập các đặc điểm , như thế này:

trait Stuff {
    private $baz = 'baz';
    public function bar() {
        return $this->baz;
    }
}

class Cls {
    use Stuff;  // import traits like this
}

$foo = new Cls;
echo $foo->bar(); // spits out 'baz'

3

Các usetừ khóa là để đặt bí danh trong PHP và nó không nhập khẩu các lớp học. Điều này thực sự có ích
1) Khi bạn có các lớp có cùng tên trong các không gian tên khác nhau
2) Tránh sử dụng tên lớp thực sự dài nhiều lần.


2

Không gian tên được sử dụng để xác định đường dẫn đến một tệp cụ thể có chứa một lớp, vd

namespace album/className; 

class className{
//enter class properties and methods here
}

Sau đó, bạn có thể đưa lớp cụ thể này vào một tệp php khác bằng cách sử dụng từ khóa "sử dụng" như thế này:

use album/className;

class album extends classname {
//enter class properties and methods
}

LƯU Ý: Không sử dụng đường dẫn đến tệp chứa lớp để thực hiện, mở rộng sử dụng để khởi tạo một đối tượng mà chỉ sử dụng không gian tên.


2

Sử dụng từ khóa "sử dụng" là để rút ngắn không gian tên. Bạn có thể sử dụng cả với răng cưa và không có nó. Không có bí danh, bạn phải sử dụng phần cuối của không gian tên đầy đủ.

<?php
    use foo\bar\lastPart;
    $obj=new lastPart\AnyClass(); //If there's not the line above, a fatal error will be encountered.
?>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.