PHP'de “use” anahtar kelimesi nasıl çalışır ve onunla sınıfları alabilir miyim?


136

Sınıflı bir dosyam var Resp. Yol:

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

Ve index.phpbu dizinde bir dosya var :

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

Bu index.phpdosyada bir sınıfı başlatmak istiyorum Resp.

$a = new Resp();

Ben bir sınıf ile dosyayı dahil etmek requireveya includeanahtar kelimeler kullanabilirsiniz biliyorum :

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

Ama requireveya kullanmadan sınıfları içe aktarmak istiyorum include. useAnahtar kelimenin nasıl çalıştığını anlamaya çalışıyorum. Tez adımları denedim ama hiçbir şey işe yaramaz:

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();

Diyor ki:

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

Anahtar kelime nasıl useçalışır? Sınıfları içe aktarmak için kullanabilir miyim?


1
Dosyaları içe aktarmadan yapamazsınız. Lütfen akışı değiştirmeyin. Ayrıca ad alanları gerçekten PHP'de kullanılmaz. Tıpkı VB.NET gibi
Cole Johnson

14
@ cole-johnson, seninle aynı fikirde değil. Symfony namespaces etrafında inşa edilmiştir . Aslında ad alanlarını kullanmıyorsanız Symfony yoktur
Green

Yanıtlar:


80

usehiçbir şey içermez. Yalnızca belirtilen ad alanını (veya sınıfı) geçerli kapsama alır

Sınıfların otomatik olarak yüklenmesini istiyorsanız - otomatik yükleme hakkında bilgi edinin


@ G-Man sorulara cevap veriyor.
zerkms

188

Hayır, useanahtar kelimeyle bir sınıfı içe aktaramazsınız . include/ requireİfadesini kullanmalısınız . Bir PHP otomatik yükleyici kullansanız bile, otomatik yükleyicinin includeya requiredahili ya da dahili olarak kullanması gerekecektir .

Kullanım anahtar kelimesinin amacı :

Aynı ada sahip iki sınıfınızın olduğu bir durumu düşünün; garip bulacaksınız, ancak büyük bir MVC yapısı ile çalışırken, olur. Aynı ada sahip iki sınıfınız varsa, bunları farklı ad alanlarına koyun. Şimdi otomatik yükleyicinizin her iki sınıfı da yüklediğini (bunu yaparak require) ve sınıf nesnesini kullanmak üzereyken düşünün . Bu durumda, derleyici, ikisi arasında hangi sınıf nesnesinin yükleneceği konusunda karışık olacaktır. Derleyicinin bir karar vermesine yardımcı olmak için, useifadeyi , hangisinin kullanılacağına karar verebilmesi için kullanabilirsiniz .

Günümüzde büyük çerçeveler kullanımını yapmak includeveya requireüzeri composervepsr

1) besteci

2) PSR-4 otomatik yükleyici

Bunları gözden geçirmek size daha fazla yardımcı olabilir. Tam bir sınıfı ele almak için bir takma ad da kullanabilirsiniz. Aynı adı taşıyan iki sınıfınız olduğunu varsayalım, örneğin Maileriki farklı ad alanı ile:

namespace SMTP;
class Mailer{}

ve

namespace Mailgun;
class Mailer{}

Ve her iki Mailer sınıfını aynı anda kullanmak istiyorsanız, bir takma ad kullanabilirsiniz.

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

Daha sonra kodunuzda bu sınıf nesnelerine erişmek istiyorsanız, aşağıdakileri yapabilirsiniz:

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

Orijinal sınıfa atıfta bulunacaktır.

Bazıları, benzer sınıf isimleri olmadığından, useanahtar kelime kullanılmadığından şaşırabilir . Argüman, argüman olarak kullanılacak sınıfla yürütüldüğünde __autoload($class)otomatik olarak çağrılacak işlevi kullanabilirsiniz useve bu, sınıfı çalışma zamanında ve gerektiğinde anında yüklemenize yardımcı olabilir.

Sınıf otomatik yükleyici hakkında daha fazla bilgi için bu cevaba başvurun .


neden sadece farklı bir sınıf adı kullanmıyorsunuz?
ilahi

15
@divine. Sınıflar 3. taraf satıcılardan olabilir
Dayo

3
@divine. Her iki çarpışan sınıf da 3. taraflardan geliyorsa ne olur?
Dayo

2
@divine Kural olarak, ad alanı <vendorName> / <packageName> olacak, böylece zaten çözülmüş olacak. Sözleşmenin ardından ambalajcının başka bir satıcıdan aynı satıcı adını kabul etmesi imkansızdır. Packagist.org, paketlerin besteci kurulumu için kullanılan PHP deposudur.
Tpojka

1
@ root önemli değil, sadece çalışma süresine ne kullanılacağını söyler. Sanki bir araba kullanıyorsunuz ve sinyal size ilerlemenizi söylüyor ve kırıyorsunuz, böyle bir useifade derleyicinin bunu benim için yüklemesini söyleyecek gibi . Anladım canım!
Rajan Rawal

23

Bir Ad Alanı'nın ne olduğunu düşünmeyin .

Ad alanı temel olarak , Sınıf yolu benzersizliğini sağlamak için yalnızca bir Sınıf önekidir (İşletim Sistemindeki dizin gibi) .

Ayrıca, her şeyi açıklığa kavuşturmak için, use deyimi yalnızca Ad Alanları'nızı diğer adlarla örtüşen bir şey yapmaz, böylece kısayolları kullanabilir veya aynı dosyaya ancak aynı Ad'a sahip farklı Adlara sahip Sınıfları aynı dosyaya ekleyebilirsiniz .

Örneğin:

// 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();
}

PHP Ad Alanları ve otomatik yüklemenin (eski yolun yanı sıra Composer ile yeni yolun) nasıl çalıştığını bilmek istiyorsanız, bu konu hakkında yazdığım blog gönderisini okuyabilirsiniz: https://enterprise-level-php.com/ / 25 2017/12 /-büyü-arkası autoloading-php-files-kullanma-composer.html


8

Yine de sınıfı dahil etmeniz / zorunlu tutmanız gerekir, aksi takdirde PHP ad alanını bilmez. Yine
de aynı dosyada yapmak zorunda değilsiniz . Örneğin bir bootstrap dosyasında yapabilirsiniz. (veya bir otomatik yükleyici kullanın, ancak aslında konu bu değil)


4

Sorun büyük olasılıkla sınıfın adını alacak bir otomatik yükleyici kullanmanız gerekecek (bu durumda '\' tarafından kesilecek) ve bir dizin yapısına eşleyeceksiniz.

Otomatik yükleme ile ilgili bu makaleye göz atabilirsinizPHP'nin işleviyle . Bu tür işlevselliklerin zaten çerçevelerde birçok uygulaması vardır.

Aslında daha önce bir tane uyguladım. İşte bir bağlantı .


Bununla birlikte bir sorun var. Tam bir yol oluşturması için özyinelemeli bir modele ihtiyacı vardır. Şu anda sadece tek seviyeli ad alanlarını ele alıyor.
Tyler Carter

3

Green'e katılıyorum, Symfony'nin isim alanına ihtiyacı var, neden onları kullanmıyorsunuz?

Örnek bir denetleyici sınıfı şu şekilde başlar:

ad alanı Acme \ DemoBundle \ Controller;

Symfony \ Bundle \ FrameworkBundle \ Controller \ Controller kullanın;

class WelcomeController Denetleyiciyi genişletiyor {...}


3

Sınıfları içe aktarmak için kullanabilir miyim?

Yukarıdaki örneklerin yanı sıra böyle yapamazsınız. Ayrıca , aşağıdaki gibi özellikleriuse içe aktarmak için sınıfların içindeki anahtar kelimeyi kullanabilirsiniz :

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

useAnahtar kelime PHP aliasing içindir ve sınıfları içe aktarmaz. Bu gerçekten yardımcı olur
1) Farklı ad alanlarında aynı ada sahip sınıflarınız olduğunda
2) Gerçekten uzun sınıf adını tekrar tekrar kullanmaktan kaçının.


2

Ad alanı, sınıf içeren belirli bir dosyanın yolunu tanımlamak için kullanılır;

namespace album/className; 

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

Daha sonra, "use" anahtar kelimesini kullanarak bu belirli sınıfı başka bir php dosyasına ekleyebilirsiniz:

use album/className;

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

NOT: Uygulanacak sınıfı içeren dosyanın yolunu kullanmayın, nesneyi örneklemek için kullanım süresini uzatın, yalnızca ad alanını kullanın.


2

"Use" anahtar sözcüğünü kullanmak, ad alanı değişmezlerini kısaltmak içindir. Hem takma adla hem de onsuz kullanabilirsiniz. Takma ad olmadan tam ad alanının son bölümünü kullanmalısınız.

<?php
    use foo\bar\lastPart;
    $obj=new lastPart\AnyClass(); //If there's not the line above, a fatal error will be encountered.
?>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.