Bir nesnenin niteliksiz (kısa) sınıf adını nasıl alabilirim?


153

Tam ad alanı sınıfını belirtmeden PHP ad boşluklu ortamda bir nesnenin sınıfını nasıl kontrol ederim.

Örneğin bir nesne kütüphanem / Varlık / Sözleşme / Adım olduğunu varsayalım.

Get_class, tam ad alanı sınıfını döndürdüğü için aşağıdaki kod çalışmaz.

If(get_class($object) == 'Name') {
... do this ...
}

Namespace magic anahtar sözcüğü geçerli ad alanını döndürür; bu, test edilen nesnenin başka bir ad alanı varsa işe yaramaz.

Sadece ad alanlarıyla tam sınıf adını belirtebilirim, ancak bu kodun yapısında kilitli görünüyor. Ayrıca ad alanını dinamik olarak değiştirmek istersem çok kullanmıyorum.

Herkes bunu yapmak için etkili bir yol düşünebilir. Sanırım bir seçenek normal ifade.


Anlamsız görünüyor, çünkü farklı ad alanları içinde aynı sınıf isimleri tanımlanmış olabilir, peki bunu nasıl halledeceksiniz? Bunun nedeni, numunenizde tam nitelikli sınıf adı döndürülmesidir
Alma Do

Mobil bir cihazdayım, bu yüzden iyi bir cevap gönderemiyorum, ancak çözüm yansıma, özellikle ReflectionClass :: getShortName - php.net/manual/en/reflectionclass.getshortname.php
lonesomeday

Bunu istemek için bir neden arayan insanlar için: ortak bir temel sınıftaki yardımcı bir işlevde yararlı olabilir (yani çoklu ad alanları bu durumda asla bir sorun değildir).
Darren Cook

Yanıtlar:


182

Bunu yansıma ile yapabilirsiniz. Özellikle, ReflectionClass::getShortNamesınıfın ad alanı olmadan adını alan yöntemi kullanabilirsiniz .

İlk olarak, bir ReflectionClassörnek oluşturmanız ve ardından getShortNamebu örneğin yöntemini çağırmanız gerekir :

$reflect = new ReflectionClass($object);
if ($reflect->getShortName() === 'Name') {
    // do this
}

Ancak, bunun istenebileceği birçok durum düşünemiyorum. Nesnenin belirli bir sınıfın üyesi olmasını istiyorsanız, sınama yolu budur instanceof. Belirli kısıtlamaları bildirmek için daha esnek bir yol istiyorsanız, bunu yapmanın yolu bir arabirim yazmak ve kodun bu arabirimi uygulamasını gerektirmektir. Yine, bunu yapmanın doğru yolu instanceof. (Bunu yapabilirsiniz ReflectionClass, ancak çok daha kötü bir performansa sahip olacaktır.)


1
@ Greg.Forbes Çünkü Tenantgeçerli ad alanında mevcut değil. var_dump($tenant instanceof \Library\Entity\People\Tenant)Bunun yerine deneyin . Ayrıca, useoperatörün nasıl kullanılacağını ve PHP ad alanlarının ardındaki genel konsepti araştırın !
lonesomeday

3
Önde böyle bir eğik çizgi eklemek zorunda kaldım$reflect = new \ReflectionClass($object);
prograhammer

7
Genellikle benim uygulamada çok fazla ReflectionClass voodoo yapmak istemiyorum çünkü yanlış kullanılırsa (korunan yöntemler halka açık hale geliyor) beklenmedik sonuçlara yol açabilir. Bunun yerine PHP sihirli sabitler üzerinde basit dize değiştirme kullanabilirsiniz: str_replace(__NAMESPACE__ . '\\', '', __CLASS__);. Aynı zamanda çok daha hızlı, performans açısından.
Franklin P Strube

2
@FranklinPStrube Bir şeyi kaçırmadıkça, nesnenin sınıfı yerine geçerli sınıfın kısa adını alır. Yansıtma kullanımının genellikle Yanlış Yaptığınız anlamına geldiğini kabul ediyorum.
lonesomeday

1
Birçok kişi yansımaları geçersiz kılmak için yansımaları kullanır, yani KÖTÜ. Böyle yapma! Ancak genel olarak Yansımalar kullanımının Voodoo ve Yanlış Yapması olduğunu belirtmek insanlara yanlış izlenim verir. Onlardan kaçınmamalısınız, onları anlamalı ve ne zaman faydalı olduklarını ve hangi soyutlama düzeyinde olduğunu bilmelisiniz.
Vanja

131

(new \ReflectionClass($obj))->getShortName(); performans açısından en iyi çözümdür.

Sunulan çözümlerden hangisinin en hızlı olduğunu merak ettim, bu yüzden küçük bir test yaptım.

Sonuçlar

Reflection: 1.967512512207 s ClassA
Basename:   2.6840535163879 s ClassA
Explode:    2.6507515668869 s ClassA

kod

namespace foo\bar\baz;

class ClassA{
    public function getClassExplode(){
        return explode('\\', static::class)[0];
    }

    public function getClassReflection(){
        return (new \ReflectionClass($this))->getShortName();
    }

    public function getClassBasename(){
        return basename(str_replace('\\', '/', static::class));
    }
}

$a = new ClassA();
$num = 100000;

$rounds = 10;
$res = array(
    "Reflection" => array(),
    "Basename" => array(),
    "Explode" => array(),
);

for($r = 0; $r < $rounds; $r++){

    $start = microtime(true);
    for($i = 0; $i < $num; $i++){
        $a->getClassReflection();
    }
    $end = microtime(true);
    $res["Reflection"][] = ($end-$start);

    $start = microtime(true);
    for($i = 0; $i < $num; $i++){
        $a->getClassBasename();
    }
    $end = microtime(true);
    $res["Basename"][] = ($end-$start);

    $start = microtime(true);
    for($i = 0; $i < $num; $i++){
        $a->getClassExplode();
    }
    $end = microtime(true);
    $res["Explode"][] = ($end-$start);
}

echo "Reflection: ".array_sum($res["Reflection"])/count($res["Reflection"])." s ".$a->getClassReflection()."\n";
echo "Basename: ".array_sum($res["Basename"])/count($res["Basename"])." s ".$a->getClassBasename()."\n";
echo "Explode: ".array_sum($res["Explode"])/count($res["Explode"])." s ".$a->getClassExplode()."\n";

Sonuçlar beni gerçekten şaşırttı. Patlama çözümünün en hızlı yol olacağını düşündüm ...


1
Mükemmel cevap. Aynı kodu çalıştırıyordum ama farklı bir sonuç aldım (Macbook Pro i7, 16 GB ram). Yansıma: 0.382, Basename: 0.380, Patlama: 0.399. Bence bu sisteme neyin en iyi olduğuna bağlı ...
Tobias Nyholm

4
Bu kodla PHP 10.000 kez çalıştırın ve daha iyi bir sonuç elde edin. Yukarıdakiler bazı havuzlardan yansımayı getirebilir, ancak bu uygulamaların olağan davranışı değildir. Sadece bir veya iki kez ihtiyaç duyarlar.
LeMike

6
... Testinizdeki Sınıf A küçük nesneden çok daha önemli bir nesne üzerinde bir ReflectionClass başlatmasını ben merak bu test tutma doğrudur yapar
Joe Green

2
100000 yerine tek bir yineleme yapmak çok farklı bir sonuç verir: Yansıma: 1.0967254638672 100000th / s ClassA Temel Adı: 0.81062316894531 100000th / s ClassA Patlat: 0.50067901611328 100000th / s
ClassA

1
patlayabilir ('\\', statik :: sınıf) [0]? ad alanının ilk bölümünü döndürmüyor mu? ilk bölümü değil, son bölümü
dönmelidir

86

Https://stackoverflow.com/a/25472778/2386943 testine substr ekledim ve her ikisi de i5 ile test edebileceğim en hızlı yol (CentOS PHP 5.3.3, Ubuntu PHP 5.5.9).

$classNameWithNamespace=get_class($this);
return substr($classNameWithNamespace, strrpos($classNameWithNamespace, '\\')+1);

Sonuçlar

Reflection: 0.068084406852722 s ClassA
Basename: 0.12301609516144 s ClassA
Explode: 0.14073524475098 s ClassA
Substring: 0.059865570068359 s ClassA 

kod

namespace foo\bar\baz;
class ClassA{
  public function getClassExplode(){
    $c = array_pop(explode('\\', get_class($this)));
    return $c;
  }

  public function getClassReflection(){
    $c = (new \ReflectionClass($this))->getShortName();
    return $c;
  }

  public function getClassBasename(){
    $c = basename(str_replace('\\', '/', get_class($this)));
    return $c;
  }

  public function getClassSubstring(){
    $classNameWithNamespace = get_class($this);
    return substr($classNameWithNamespace, strrpos($classNameWithNamespace, '\\')+1);
  }
}

$a = new ClassA();
$num = 100000;

$rounds = 10;
$res = array(
    "Reflection" => array(),
    "Basename" => array(),
    "Explode" => array(),
    "Substring" => array()
);

for($r = 0; $r < $rounds; $r++){

  $start = microtime(true);
  for($i = 0; $i < $num; $i++){
    $a->getClassReflection();
  }
  $end = microtime(true);
  $res["Reflection"][] = ($end-$start);

  $start = microtime(true);
  for($i = 0; $i < $num; $i++){
    $a->getClassBasename();
  }
  $end = microtime(true);
  $res["Basename"][] = ($end-$start);

  $start = microtime(true);
  for($i = 0; $i < $num; $i++){
    $a->getClassExplode();
  }
  $end = microtime(true);
  $res["Explode"][] = ($end-$start);

  $start = microtime(true);
  for($i = 0; $i < $num; $i++){
    $a->getClassSubstring();
  }
  $end = microtime(true);
  $res["Substring"][] = ($end-$start);
}

echo "Reflection: ".array_sum($res["Reflection"])/count($res["Reflection"])." s ".$a->getClassReflection()."\n";
echo "Basename: ".array_sum($res["Basename"])/count($res["Basename"])." s ".$a->getClassBasename()."\n";
echo "Explode: ".array_sum($res["Explode"])/count($res["Explode"])." s ".$a->getClassExplode()."\n";
echo "Substring: ".array_sum($res["Substring"])/count($res["Substring"])." s ".$a->getClassSubstring()."\n";

== GÜNCELLEME ==

@MrBandersnatch tarafından yapılan yorumlarda belirtildiği gibi, bunu yapmanın daha hızlı bir yolu var:

return substr(strrchr(get_class($this), '\\'), 1);

"SubstringStrChr" ile güncellenmiş test sonuçları (yaklaşık 0.001 saniyeye kadar tasarruf sağlar):

Reflection: 0.073065280914307 s ClassA
Basename: 0.12585079669952 s ClassA
Explode: 0.14593172073364 s ClassA
Substring: 0.060415267944336 s ClassA
SubstringStrChr: 0.059880912303925 s ClassA

5
Verimlilik için listelediğimiz için bunu en hızlı buldum, bu çözümde sağlanan testle karşılaştırma substr (strrchr (get_class ($ obj), '\\'), 1); Yansıma: 0.084223914146423 s ClassA - Temel Adı: 0.13206427097321 s ClassA - Patlat: 0.15331919193268 s ClassA - Alt dize: 0.068068099021912 s ClassA - Strrchar: 0.06472008228302 s ClassA -
ctatro85

Ben sadece bu iş parçacığına rastladı ve test etmek için ek bir kıyaslama ekledim str_replace(__NAMESPACE__ . '\\', '', __CLASS__);. Zayıf bir sanal makinede elde edilen sonuçlar, tüm bunlardan neredeyse iki kat daha hızlı olduğunu gösterdi. php -f bench.php Reflection: 0.44037771224976 s ClassA Basename: 0.48089025020599 s ClassA Explode: 0.54955270290375 s ClassA Substring: 0.38200764656067 s ClassA Frank's Custom Benchmark: 0.22782742977142 s ClassA
Franklin P Strube

1
@MrBandersnatch haklısınız. Çözümünüzü test ettim ve beni yaklaşık 0.001 s kurtardı. Cevabımı sizinkilerle güncelledim!
MaBi

3
Uyarı: Bu kod genel ad alanındaki sınıflarla çalışmaz (yani: tam adları kısa adlarına eşittir)! Gibi deney şey ben tavsiye: if ($pos = strrchr(static::class, '\\')) { .. } else { ... }.
Tristan Jahier

1
Küresel ad alanında da çalışmasını sağlamak için, sınıf adını ters eğik çizgi ile $classNameShort = substr(strrchr('\\' . get_class($this), '\\'), 1);
başlamanız yeterlidir

26

Laravel PHP framework kullanıyorsanız bunu yapmanın daha kolay bir yolu:

<?php

// usage anywhere
// returns HelloWorld
$name = class_basename('Path\To\YourClass\HelloWorld');

// usage inside a class
// returns HelloWorld
$name = class_basename(__CLASS__);

8
Bu yerleşik bir php işlevi değil, laravel tarafından sağlanan bir yardımcı işlev gibi görünüyor.
Steve Buzonas

7
Sanırım bunu söyledi
Scott

4
Teşekkürler, Laravel kullanıyorum ve bu cevap bana çok zaman kazandırdı.
Jeremy Wadhams


18

Bunu kullanıyorum:

basename(str_replace('\\', '/', get_class($object)));

Ayrıca deneyebilirsiniz: $ className = explode ('\\', basename (get_class ($ this))); $ className = dizi_pop ($ className); düz sınıf adını almak için. Veya substr.
dompie

13
Yalnızca Windows'ta çalışır Windows'ta, eğik çizgi (/) ve ters eğik çizgi () dizin ayırıcı karakter olarak kullanılır. Diğer ortamlarda, eğik çizgi (/) php.net/manual/tr/function.basename.php
OzzyCzech

Şimdi düzelttim. Teşekkürler @OzzyCzech.
Theodore R. Smith

1
@OzzyCzech Ben sadece Windows Ubuntu .... maddening taşırken bu koştu. MaBi'nin güncellemesinde belirtilen çözümü kullanarak yaralayın.
Chris Baker

@OzzyCzech Come sadece Windows'da nasıl çalışır? soru, yıllar önce de yanılmıyorsam tam nitelikli ad alanı adı ile ilgiliydi ve ad alanları işletim sistemine özgü değil ve her zaman Windows dizin ayırıcısı gibi ters eğik çizgi ile.
FantomX1

17

Kısa adı tek astar olarak almak için ( PHP 5.4'ten beri ):

echo (new ReflectionClass($obj))->getShortName();

Temiz bir yaklaşım ve makul hızlı .


1
Bunun kıyaslamalarda bir dizge çıkarmasıyla nasıl karşılaştırıldığını merak ediyorum. Bu çok daha yavaş olacak gibi görünüyor.
Doğrulanmamış İletişim

12

Kendimi kullanılamayan benzersiz bir durumda buldum instanceof(özellikle isim özellikli özellikler) ve kısa isme mümkün olan en verimli şekilde ihtiyacım vardı , bu yüzden kendime küçük bir kıyaslama yaptım. Bu sorudaki cevapların tüm farklı yöntemlerini ve varyasyonlarını içerir.

$bench = new \xori\Benchmark(1000, 1000);     # https://github.com/Xorifelse/php-benchmark-closure
$shell = new \my\fancy\namespace\classname(); # Just an empty class named `classname` defined in the `\my\fancy\namespace\` namespace

$bench->register('strrpos', (function(){
    return substr(static::class, strrpos(static::class, '\\') + 1);
})->bindTo($shell));

$bench->register('safe strrpos', (function(){
    return substr(static::class, ($p = strrpos(static::class, '\\')) !== false ? $p + 1 : 0);
})->bindTo($shell));

$bench->register('strrchr', (function(){
    return substr(strrchr(static::class, '\\'), 1);
})->bindTo($shell));

$bench->register('reflection', (function(){
    return (new \ReflectionClass($this))->getShortName();
})->bindTo($shell));

$bench->register('reflection 2', (function($obj){
    return $obj->getShortName();
})->bindTo($shell), new \ReflectionClass($shell));

$bench->register('basename', (function(){
    return basename(str_replace('\\', '/', static::class));
})->bindTo($shell));

$bench->register('explode', (function(){
    $e = explode("\\", static::class);
    return end($e);
})->bindTo($shell));

$bench->register('slice', (function(){
    return join('',array_slice(explode('\\', static::class), -1));
})->bindTo($shell));    

print_r($bench->start());

Bütün sonucun bir listesi olduğunu burada ama burada önemli noktaları şunlardır:

  • Eğer sen zaten kullanım yansıması gidiyoruz kullanarak $obj->getShortName()en hızlı yöntemdir ancak ; yansıma sadece kısa adı almak için kullanmak neredeyse en yavaş yöntemdir.
  • 'strrpos'nesne bir isim alanında değilse yanlış bir değer döndürebilir bu yüzden 'safe strrpos'biraz daha yavaş ise bu kazanan olduğunu söyleyebilirim.
  • Yapmak için 'basename'Linux ve Windows arasında uyumlu sen kullanımına gerek str_replace()bu yöntemi hepsini yavaş yapar.

Basitleştirilmiş bir sonuç tablosu, en yavaş yönteme kıyasla hız ölçülür:

+-----------------+--------+
| registered name | speed  |
+-----------------+--------+
| reflection 2    | 70.75% |
| strrpos         | 60.38% |
| safe strrpos    | 57.69% |
| strrchr         | 54.88% |
| explode         | 46.60% |
| slice           | 37.02% |
| reflection      | 16.75% |
| basename        | 0.00%  |
+-----------------+--------+

8

Sen kullanabilirsiniz explodead ayrılması ve için endsınıf adını almak için:

$ex = explode("\\", get_class($object));
$className = end($ex);

7

Yii yolu

\yii\helpers\StringHelper::basename(get_class($model));

Yii bu yöntemi Gii kod üretecinde kullanır

Yöntem belgeleri

Bu yöntem, işletim sisteminden bağımsız olarak hem \ hem de / dizin ayırıcıları olarak işlem görmesi dışında, php basename () işlevine benzer. Bu yöntem esas olarak php ad alanlarında çalışmak üzere oluşturulmuştur. Gerçek dosya yolları ile çalışırken, php basename () sizin için iyi çalışmalıdır. Not: bu yöntem gerçek dosya sisteminin veya ".." gibi yol bileşenlerinin farkında değildir.

Daha fazla bilgi:

https://github.com/yiisoft/yii2/blob/master/framework/helpers/BaseStringHelper.php http://www.yiiframework.com/doc-2.0/yii-helpers-basestringhelper.html#basename()-detail


Stack Overflow'a hoş geldiniz. Lütfen cevabınız için daha fazla bilgi veriniz. Bu ne yapar ve nasıl kullanabilir.
Jens

1
Bu benim için Windows üzerinde çalıştı, ancak Linux'ta değil, belki de ad alanları Windows dizinleri biçiminde '\' ters eğik çizgiler olduğundan, linux basename dizin ayırıcılarının eğik çizgi '/' olduğunu düşünüyor. Ben de strtr ile çalıştım. ' basename (strtr ($ class, '\\', '/'))
FantomX1

6

İşte PHP 5.4+ için basit bir çözüm

namespace {
    trait Names {
        public static function getNamespace() {
            return implode('\\', array_slice(explode('\\', get_called_class()), 0, -1));
        }

        public static function getBaseClassName() {
            return basename(str_replace('\\', '/', get_called_class()));
        }
    }
}

Geri dönüş ne olacak?

namespace x\y\z {
    class SomeClass {
        use \Names;
    }

    echo \x\y\z\SomeClass::getNamespace() . PHP_EOL; // x\y\z
    echo \x\y\z\SomeClass::getBaseClassName() . PHP_EOL; // SomeClass
}

Genişletilmiş sınıf adı ve ad alanı aşağıdakiler için iyi çalışır:

namespace d\e\f {

    class DifferentClass extends \x\y\z\SomeClass {

    }

    echo \d\e\f\DifferentClass::getNamespace() . PHP_EOL; // d\e\f
    echo \d\e\f\DifferentClass::getBaseClassName() . PHP_EOL; // DifferentClass
}

Global isim alanındaki sınıfa ne dersiniz?

namespace {

    class ClassWithoutNamespace {
        use \Names;
    }

    echo ClassWithoutNamespace::getNamespace() . PHP_EOL; // empty string
    echo ClassWithoutNamespace::getBaseClassName() . PHP_EOL; // ClassWithoutNamespace
}

3

Bir sınıfın içinden çağrılan sınıf adını bilmeniz gerekiyorsa ve ad alanını istemiyorsanız, bunu kullanabilirsiniz

$calledClass = get_called_class();
$name = strpos($calledClass, '\\') === false ?
    $calledClass : substr($calledClass, strrpos($calledClass, '\\') + 1);

Bu, bir sınıf içinde diğer sınıflar tarafından genişletilen bir yönteminiz olduğunda harikadır. Ayrıca, ad alanları hiç kullanılmadığında da bu işe yarar.

Misal:

<?php
namespace One\Two {
    class foo
    {
        public function foo()
        {
            $calledClass = get_called_class();
            $name = strpos($calledClass, '\\') === false ?
                $calledClass : substr($calledClass, strrpos($calledClass, '\\') + 1);

            var_dump($name);
        }
    }
}

namespace Three {
    class bar extends \One\Two\foo
    {
        public function bar()
        {
            $this->foo();
        }
    }
}

namespace {
    (new One\Two\foo)->foo();
    (new Three\bar)->bar();
}

// test.php:11:string 'foo' (length=3)
// test.php:11:string 'bar' (length=3)

2

@MaBi'nin cevabına dayanarak bunu yaptım:

trait ClassShortNameTrait
{
    public static function getClassShortName()
    {
        if ($pos = strrchr(static::class, '\\')) {
            return substr($pos, 1);
        } else {
            return static::class;
        }
    }
}

Hangi gibi kullanabilirsiniz:

namespace Foo\Bar\Baz;

class A
{
    use ClassShortNameTrait;
}

A::classdöner Foo\Bar\Baz\A, ama A::getClassShortName()döner A.

PHP için çalışır> = 5.5.


2

Bu eski bir yazı olduğunu biliyorum ama bu ne kullanıyorum - Yukarıda yayınlanan tüm daha hızlı sadece bu yöntemi sınıfından çağırmak, Yansıma kullanmaktan çok daha hızlı

namespace Foo\Bar\Baz;

class Test {
    public function getClass() {
        return str_replace(__NAMESPACE__.'\\', '', static::class);
    }
}

Ne yazık ki, sadece sınıf adını dize olarak değil, adını istediğiniz sınıfta çağırıyorsanız çalışır.
jurchiks

1

Get_class, nwhiting dot com adresinde tarafımdan yayınlandığı dokümantasyon sayfasında bulundu .

function get_class_name($object = null)
{
    if (!is_object($object) && !is_string($object)) {
        return false;
    }

    $class = explode('\\', (is_string($object) ? $object : get_class($object)));
    return $class[count($class) - 1];
}

Ancak ad alanları fikri kodunuzu yapılandırmaktır. Bu aynı zamanda birden çok ad alanında aynı ada sahip sınıflara sahip olabileceğiniz anlamına gelir. Teorik olarak, geçtiğiniz nesnenin adı (soyulmuş) sınıf adına sahip olabilirken, yine de beklediğinizden tamamen farklı bir nesne olabilir.

Bunun yanı sıra, belirli bir temel sınıfı kontrol etmek isteyebilirsiniz , bu durumda get_classhile yapmaz. Operatöre göz atmak isteyebilirsiniz instanceof.


1

Sınıfın bir ad alanı olmadığında beklenmeyen bir sonuç alabilirsiniz. Yani get_classgeri döner Foo, sonra $baseClassolur oo.

$baseClass = substr(strrchr(get_class($this), '\\'), 1);

Bu, get_classters eğik çizgi ile önek ekleyerek kolayca düzeltilebilir :

$baseClass = substr(strrchr('\\'.get_class($this), '\\'), 1);

Artık ad alanı olmayan sınıflar da doğru değeri döndürecektir.


1

İyi bir eski normal ifade, daha önce gösterilen yöntemlerin çoğundan daha hızlı görünmektedir:

// both of the below calls will output: ShortClassName

echo preg_replace('/.*\\\\/', '', 'ShortClassName');
echo preg_replace('/.*\\\\/', '', 'SomeNamespace\SomePath\ShortClassName');

Bu, kısa sınıf adı veya tam nitelikli (standart) bir sınıf adı girdiğinizde bile çalışır.

Normal ifadenin yaptığı şey, son ayırıcı bulunana kadar (aynı zamanda tüketilen) önceki tüm karakterleri tüketmesidir. Böylece kalan dize kısa sınıf adı olacaktır.

Farklı bir ayırıcı (örn. /) Kullanmak istiyorsanız, bunun yerine bu ayırıcıyı kullanın. Ters eğik çizgiden (yani. \) Ve ayrıca giriş düzenindeki dikiş çeşidinden (örn. /) Kaçmayı unutmayın.


1

Çünkü "ReflectionClass" sürüm bağımlı olabilir sadece kullanın kullanın:

if(class_basename(get_class($object)) == 'Name') {
... do this ...
}

hatta net

if(class_basename(ClassName::class) == 'ClassName') {
... do this ...
}

0

Php.net alıntılama:

Windows'ta, eğik çizgi (/) ve ters eğik çizgi () dizin ayırıcı karakter olarak kullanılır. Diğer ortamlarda, eğik çizgi (/).

Bu bilgilere dayanarak ve arzzzen yanıtından genişleyerek, bu hem Windows hem de Nix * sistemlerinde çalışmalıdır:

<?php

if (basename(str_replace('\\', '/', get_class($object))) == 'Name') {
    // ... do this ...
}

Not: Yansıtmaya ReflectionClasskarşı bir ölçüt yaptım basename+str_replace+get_classve yansıma kullanmanın taban adı yaklaşımını kullanmaktan kabaca% 20 daha hızlı olduğunu, ancak YMMV'yi kullandım.


0

Her ortamda çalışan en hızlı ve en kolay çözüm:

<?php

namespace \My\Awesome\Namespace;

class Foo {

  private $shortName;

  public function fastShortName() {
    if ($this->shortName === null) {
      $this->shortName = explode("\\", static::class);
      $this->shortName = end($this->shortName);
    }
    return $this->shortName;
  }

  public function shortName() {
    return basename(strtr(static::class, "\\", "/"));
  }

}

echo (new Foo())->shortName(); // "Foo"

?>

1
Bu yüzden PHP iç sınıf bilgi operatörleri olsaydı. Basit bir şey yapmak için harici bir yansıtıcıyı örneklemek $Object->__class->getShortName()gerçekten PHP hakkında beni kızdırıyor. Yaklaşımınız işe yarıyor, ancak şimdi sadece bir dil kurgusu olması gerekenleri ortaya çıkarmak için sınıflarınıza somut yöntemler uyguluyorsunuz.
AgmLauncher

“Somut” olmayan PHP (veya bunları prosedürel olarak adlandırmalıyız) fonksiyonları imkansızdır. PHP 6'yı bekleyelim (eğer gelirse).
Fleshgrinder

0
$shortClassName = join('',array_slice(explode('\\', $longClassName), -1));

0

Sadece ad boşluklarını sıyırıyorsanız ve ad alanına sahip bir sınıf adında (veya yalnızca \ 'yoksa adda) son \' dan sonra bir şey istiyorsanız, şöyle bir şey yapabilirsiniz:

$base_class = preg_replace('/^([\w\\\\]+\\\\)?([^\\\\]+)$/', '$2', get_class($myobject));

Temelde, herhangi bir karakter veya ters eğik çizgi kombinasyonunu elde etmek ve son ters eğik çizgiye kadar sadece ters eğik çizgi olmayan karakterleri yukarı ve dizenin sonuna kadar döndürmek normaldir. Ekleniyor mu? ilk gruplama, kalıp eşleşmesi yoksa, tam dizeyi döndürür.


0

En hızlı ben burada buldum PHP 7.2üzerindeUbubntu 18.04

preg_replace('/^(\w+\\\)*/', '', static::class)
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.