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


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.