객체의 정규화되지 않은 (짧은) 클래스 이름을 어떻게 얻습니까?


153

전체 네임 스페이스 클래스를 지정하지 않고 PHP 네임 스페이스 환경 내에서 오브젝트 클래스를 확인하는 방법

예를 들어 객체 라이브러리 / 엔티티 / 계약 / 이름이 있다고 가정합니다.

get_class가 전체 네임 스페이스 클래스를 리턴하므로 다음 코드는 작동하지 않습니다.

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

네임 스페이스 magic 키워드는 현재 네임 스페이스를 반환하며, 테스트 된 객체에 다른 네임 스페이스가 있으면 사용되지 않습니다.

네임 스페이스로 전체 클래스 이름을 간단히 지정할 수는 있지만 코드 구조에 잠겨있는 것 같습니다. 네임 스페이스를 동적으로 변경하려는 경우에도 많이 사용되지 않습니다.

누구나 효율적인 작업 방법을 생각할 수 있습니까? 하나의 옵션이 정규식이라고 생각합니다.


다른 네임 스페이스에 동일한 클래스 이름이 정의되어 있기 때문에 무의미 해 보입니다. 어떻게 처리합니까? 이는 정규화 된 클래스 이름이 샘플에 반환되기 때문입니다.
— Alma Do

내가 괜찮은 대답을 제출할 수 있도록 나는, 모바일 장치에있어,하지만 해결책은 반사, 특히 ReflectionClass :: getShortName입니다 - php.net/manual/en/reflectionclass.getshortname.php
— lonesomeday

이것을 원하는 이유를 찾는 사람들의 경우 : 공통 기본 클래스의 도우미 함수에 유용 할 수 있습니다 (즉,이 상황에서는 여러 네임 스페이스가 문제가되지 않습니다).
— 대런 쿡

답변:


182

리플렉션으로이 작업을 수행 할 수 있습니다. 특히 ReflectionClass::getShortName네임 스페이스없이 클래스 이름을 가져 오는 메서드 를 사용할 수 있습니다 .

먼저 ReflectionClass인스턴스 를 빌드 한 다음 getShortName해당 인스턴스 의 메소드 를 호출 해야합니다.

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

그러나 이것이 바람직한 많은 상황을 상상할 수 없습니다. 객체가 특정 클래스의 멤버인지 확인하려면 테스트 방법을 사용하십시오 instanceof. 특정 제약 조건을 신호하는보다 유연한 방법을 원한다면 인터페이스를 작성하고 코드가 해당 인터페이스를 구현해야합니다. 이 작업을 수행하는 올바른 방법은입니다 instanceof. (로 할 수 ReflectionClass있지만 성능이 훨씬 떨어집니다.)


1
@ Greg.Forbes Tenant현재 네임 스페이스에 존재하지 않기 때문입니다. var_dump($tenant instanceof \Library\Entity\People\Tenant)대신 시도하십시오 . 또한 use연산자 사용법 과 PHP 네임 스페이스의 일반적인 개념 을 조사하십시오 !
— lonesomeday

3
이렇게 앞에 슬래시를 추가해야했습니다$reflect = new \ReflectionClass($object);
— 1

7
일반적으로 응용 프로그램에서 ReflectionClass 부두를 많이 사용하는 것은 좋지 않습니다. 잘못 사용하면 예기치 않은 결과가 발생할 수 있기 때문에 (보호 된 메소드가 공개되는 등). PHP 매직 상수에서 간단한 문자열 대체를 대신 사용할 수 있습니다 str_replace(__NAMESPACE__ . '\\', '', __CLASS__);. 성능면에서도 훨씬 빠릅니다.
— 프랭클린 P 스 트루 브

2
@FranklinPStrube 내가 빠진 것이 아니라면 객체 클래스가 아닌 현재 클래스의 짧은 이름을 얻습니다. 리플렉션을 사용하면 일반적으로 잘못하고 있음을 동의합니다.
— lonesomeday

1
많은 사람들이 BAD 인 멤버 가시성 재정의에 Reflections를 사용합니다. 그거 하지마! 그러나 일반적으로 리플렉션 사용은 부두와 잘못하는 것은 사람들에게 잘못된 인상을줍니다. 당신은 그것들을 피해서는 안되며, 그것들을 이해하고 그들이 유익한 시점과 추상화 수준을 알아야합니다.
— Vanja D.

131

(new \ReflectionClass($obj))->getShortName(); 성능과 관련하여 최상의 솔루션입니다.

제공된 솔루션 중 가장 빠른 솔루션이 궁금해서 약간의 테스트를 거쳤습니다.

결과

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

암호

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";

결과는 실제로 저를 놀라게했습니다. 폭발 솔루션이 가장 빠른 방법이라고 생각했습니다.


1
좋은 대답입니다. 나는 동일한 코드를 실행했지만 다른 결과를 얻었습니다 (Macbook Pro i7, 16GB 램). 반사 : 0.382, 기본 이름 : 0.380, 분해 : 0.399. 나는 그것이 당신의 시스템에 달려 있다고 생각합니다 ...
— Tobias Nyholm

4
해당 코드로 PHP 10,000 번을 실행하면 더 나은 결과를 얻을 수 있습니다. 위의 내용은 일부 풀에서 리플렉션을 가져올 수 있지만 이것은 일반적인 응용 프로그램 동작이 아닙니다. 그들은 한두 번만 필요합니다.
— LeMike

6
테스트에서 클래스 A의 작은 오브젝트보다 더 큰 오브젝트에서 ReflectionClass를 인스턴스화 할 때이 테스트가 적용되는지 궁금합니다.
— Joe Green

2
100000 대신 한 번의 반복 만 실행하면 훨씬 다른 결과를 얻을 수 있습니다. 반사 : 1.0967254638672 100000 / 초 ClassA 기본 이름 : 0.81062316894531 100000 / 초 ClassA 분해 : 0.50067901611328 100000th / s ClassA
— mcmurphy

1
explode ( '\\', 정적 :: 클래스) [0]? 네임 스페이스의 첫 번째 부분을 반환하지 않습니까? 처음이 아닌 마지막 부분을 반환해야 함
— 2oppin

86

https://stackoverflow.com/a/25472778/2386943 의 테스트에 substr을 추가 했으며 i5를 사용하여 테스트 할 수있는 가장 빠른 방법 (CentOS PHP 5.3.3, Ubuntu PHP 5.5.9)입니다.

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

결과

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

암호

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";

== 업데이트 ==

@MrBandersnatch의 의견에서 언급 했듯이이 작업을 수행하는 더 빠른 방법이 있습니다.

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

다음은 "SubstringStrChr"로 업데이트 된 테스트 결과입니다 (최대 약 0.001 초 절약).

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
우리가 효율성을 위해 목록을 작성했기 때문에이 솔루션에서 제공 한 테스트와 비교하여 이것이 가장 빠르다는 것을 알았습니다 substr (strrchr (get_class ($ obj), '\\'), 1); 반사 : 0.084223914146423의를 ClassA - 기본 이름 : 0.13206427097321의를 ClassA - 폭발 : 0.15331919193268의를 ClassA을 - 하위 문자열 : 0.068068099021912의를 ClassA - Strrchar : 0.06472008228302의를 ClassA -
— ctatro85

방금이 스레드를 발견하고 테스트 할 추가 벤치 마크를 추가했습니다 str_replace(__NAMESPACE__ . '\\', '', __CLASS__);. 약한 가상 머신의 결과는이 머신들보다 거의 두 배 빠릅니다. 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
— 프랭클린 P 스 트루 브

1
@MrBandersnatch 당신이 맞습니다. 귀하의 솔루션을 테스트했으며 약 0.001 초를 절약했습니다. 나는 당신의 답변을 업데이트했습니다!
— MaBi

3
경고 :이 코드는 전역 네임 스페이스의 클래스에서 작동하지 않습니다 (예 : 전체 이름이 짧은 이름과 동일 함)! 나는 다음과 같은 것을 테스트하는 것이 if ($pos = strrchr(static::class, '\\')) { .. } else { ... }좋습니다.
— Tristan Jahier

1
전역 네임 스페이스에서도 작동하게하려면 클래스 이름 앞에 백 슬래시를 추가하십시오.-) :$classNameShort = substr(strrchr('\\' . get_class($this), '\\'), 1);
— rosell.dk

25

Laravel PHP 프레임 워크를 사용하는 경우 더 쉬운 방법은 다음과 같습니다.

<?php

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

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

8
이것은 내장 PHP 함수가 아니며, laravel이 제공하는 도우미 함수처럼 보입니다.
— Steve Buzonas 1

6
나는 그가 말했다
— 스캇

4
고마워, 나는 Laravel을 사용하고 있으며이 답변은 많은 시간을 절약했습니다.
— Jeremy Wadhams


18

나는 이것을 사용한다 :

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

시도해 볼 수도 있습니다 : $ className = explode ( '\\', basename (get_class ($ this))); $ className = array_pop ($ className); 일반 클래스 이름을 가져옵니다. 또는 substr을 사용하십시오.
— dompie

13
Windows에서만 작동 Windows에서는 슬래시 (/)와 백 슬래시 ()가 모두 디렉토리 구분 문자로 사용됩니다. 다른 환경에서는 슬래시 (/) php.net/manual/en/function.basename.php
— OzzyCzech

나는 지금 고쳤다. 감사합니다, @OzzyCzech.
— Theodore R. Smith 5

1
@OzzyCzech Windows에서 Ubuntu로 이동하는 동안 방금이 문제가 발생했습니다. MaBi의 업데이트에 언급 된 솔루션을 사용하여 정리했습니다.
— Chris Baker

@OzzyCzech Come은 Windows에서만 어떻게 작동합니까? 몇 년 전 틀린 것이 아니라면 네임 스페이스 이름이 정식 네임 스페이스 이름에 관한 것이었고 네임 스페이스는 OS마다 다르지 않으며 항상 Windows 디렉토리 구분 기호와 같은 백 슬래시가 있습니다.
— FantomX1

16

짧은 이름을 단일 라이너로 얻으려면 ( PHP 5.4 부터 ) :

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

깔끔한 접근 방식과 합리적인 속도 입니다.


1
이것이 벤치 마크에서 문자열 추출과 어떻게 비교되는지 궁금합니다. 훨씬 느려질 것 같습니다.
— Unverified Contact

12

나는 instanceof사용할 수없는 독특한 상황 (특히 네임 스페이스 특성)을 발견했으며 가능한 가장 효율적인 방법으로 짧은 이름이 필요 했기 때문에 내 자신의 작은 벤치 마크를 수행했습니다. 이 질문에 대한 답변과 다른 모든 방법과 변형이 포함됩니다.

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

전체 결과 목록이 여기에 있지만 주요 내용은 다음과 같습니다.

  • 경우 당신이 어쨌든 사용 반사거야, 사용하는 것이 $obj->getShortName()가장 빠른 방법이다 그러나이 ; 반사 만 사용짧은 이름을 얻기 하면 거의 가장 느린 방법입니다.
  • 'strrpos'객체가 네임 스페이스에 있지 않으면 잘못된 값을 반환 할 수 있으므로 'safe strrpos'조금 느리지 만 이것이 승자라고 말할 것입니다.
  • 'basename'Linux와 Windows간에 호환되도록 하려면 str_replace()이 방법을 가장 느리게 사용해야 합니다.

단순화 된 결과 표, 속도는 가장 느린 방법과 비교하여 측정됩니다.

+-----------------+--------+
| 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

explode네임 스페이스를 분리 end하고 클래스 이름을 얻는 데 사용할 수 있습니다 .

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

7

이이 웨이

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

Yii는 Gii 코드 생성기에서이 방법을 사용합니다.

분석법 문서

이 메소드는 php 함수 basename ()과 비슷합니다. 운영체제와 독립적으로 \와 /를 모두 디렉토리 구분자로 취급한다는 점이 다릅니다. 이 방법은 주로 PHP 네임 스페이스에서 작동하도록 만들어졌습니다. 실제 파일 경로로 작업 할 때 php의 basename ()이 잘 작동합니다. 참고 :이 방법은 실제 파일 시스템이나 ".."와 같은 경로 구성 요소를 인식하지 못합니다.

추가 정보:

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


스택 오버플로에 오신 것을 환영합니다. 답변에 대한 자세한 정보를 제공하십시오. 이것이하는 일과 사용 방법
— Jens

1
네임 스페이스가 Windows 디렉토리 백 슬래시 '\'의 형식 인 반면 Linux 기본 이름은 디렉토리 구분 기호를 슬래시 '/'로 간주하기 때문에 Windows에서는 Linux에서는 그렇지 않았습니다. 그래서 strtr과 함께 일했습니다. ' basename (strtr ($ class, '\\', '/'))
— FantomX1

6

다음은 PHP 5.4+를위한 간단한 솔루션입니다.

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

무엇이 돌아 올까요?

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
}

확장 클래스 이름과 네임 스페이스는 다음과 같이 잘 작동합니다.

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
}

글로벌 네임 스페이스의 클래스는 어떻습니까?

namespace {

    class ClassWithoutNamespace {
        use \Names;
    }

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

3

클래스 내부에서 호출 된 클래스 이름을 알아야하고 네임 스페이스를 원하지 않는 경우이 이름을 사용할 수 있습니다.

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

이것은 다른 클래스에 의해 확장 된 클래스 내부에 메서드가있을 때 좋습니다. 또한 네임 스페이스가 전혀 사용되지 않는 경우에도 작동합니다.

예:

<?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의 답변을 바탕으로 다음과 같이했습니다.

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

다음과 같이 사용할 수 있습니다.

namespace Foo\Bar\Baz;

class A
{
    use ClassShortNameTrait;
}

A::class을 반환 Foo\Bar\Baz\A하지만을 A::getClassShortName()반환합니다 A.

PHP> = 5.5에서 작동합니다.


2

나는 이것이 오래된 게시물이라는 것을 알고 있지만 이것이 내가 사용하는 것입니다-위에 게시 된 모든 것보다 빠르면 클래스 에서이 메소드를 호출하면 리플렉션을 사용하는 것보다 훨씬 빠릅니다.

namespace Foo\Bar\Baz;

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

불행히도 클래스 이름 만 문자열이 아닌 원하는 클래스에서 호출하는 경우에만 작동합니다.
— jurchiks

1

get_class 의 문서 페이지 에서 nwhiting dot com 에 게시되었습니다 .

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];
}

그러나 네임 스페이스의 아이디어는 코드를 구성하는 것입니다. 또한 여러 네임 스페이스에서 같은 이름의 클래스를 가질 수 있습니다. 따라서 이론적으로 전달하는 객체의 이름은 클래스 이름을 가질 수 있지만 예상과는 완전히 다른 객체 일 수 있습니다.

그 외에도 특정 기본 클래스 를 확인하고 싶을 경우 get_class트릭을 전혀 수행하지 않습니다. 운영자를 확인하고 싶을 수도 있습니다 instanceof.


1

클래스에 네임 스페이스가 없으면 예기치 않은 결과가 발생할 수 있습니다. 즉 get_class반환 Foo, 다음 $baseClass이 될 것입니다 oo.

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

get_class백 슬래시 를 접두어 로 붙여서 쉽게 해결할 수 있습니다 .

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

이제 네임 스페이스가없는 클래스도 올바른 값을 반환합니다.


1

좋은 오래된 정규 표현식은 이전에 표시된 대부분의 방법보다 빠릅니다.

// both of the below calls will output: ShortClassName

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

따라서 이것은 짧은 클래스 이름 또는 정규화 된 (정식) 클래스 이름을 제공하는 경우에도 작동합니다.

정규식은 마지막 구분 기호가 발견 될 때까지 모든 이전 문자를 소비한다는 것입니다. 나머지 문자열은 짧은 클래스 이름입니다.

다른 구분 기호 (예 : /)를 사용하려면 해당 구분 기호를 대신 사용하십시오. 입력 패턴에서 백 슬래시 (예 : \)와 패턴 문자 (예 : /)를 이스케이프해야합니다.


1

"ReflectionClass"는 버전에 따라 다를 수 있으므로 다음을 사용하십시오.

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

심지어

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

0

php.net 인용 :

Windows에서 슬래시 (/) 및 백 슬래시 ()는 모두 디렉토리 구분 문자로 사용됩니다. 다른 환경에서는 슬래시 (/)입니다.

이 정보를 바탕으로 arzzzen 답변에서 확장하면 Windows 및 Nix * 시스템 모두에서 작동합니다.

<?php

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

참고 : 반사 에 ReflectionClass대한 벤치 마크를 basename+str_replace+get_class사용했으며 기본 이름 접근법을 사용하는 것보다 YAMV를 사용하는 것보다 약 20 % 빠릅니다.


0

모든 환경에서 작동하는 가장 빠르고 가장 쉬운 솔루션은 다음과 같습니다.

<?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
이것이 PHP에 내부 클래스 정보 연산자가 있기를 바랍니다. 외부 리플렉터를 인스턴스화하여 간단하게 $Object->__class->getShortName()PHP를 익히는 것만 큼 ​​간단 합니다. 당신의 접근 방식은 효과가 있지만, 이제는 언어 구조가 무엇인지를 드러내 기 위해 클래스에 구체적인 메소드를 배치하고 있습니다.
— AgmLauncher

"콘크리트 (concrete)"기능이없는 PHP (또는 프로 시저 호출해야 함) 기능은 불가능합니다. PHP 6을 기다립니다.
— Fleshgrinder

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

0

네임 스페이스를 제거하고 네임 스페이스가있는 클래스 이름에서 마지막 \ 다음에 무언가를 원한다면 (또는 '\'가없는 경우 이름 만) 다음과 같이 할 수 있습니다.

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

기본적으로 문자 또는 백 슬래시의 조합을 가져오고 마지막 백 슬래시까지 백 슬래시가 아닌 문자 만 문자열 끝까지 반환하는 정규식입니다. 추가? 첫 번째 그룹화는 패턴 일치가 존재하지 않으면 전체 문자열을 반환한다는 의미입니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.